Build function -> file map
Serialize/deserialize file name Define FileEntryImpl Provide IrReturnableBlock with information about source file Move file iteration in NoJavaUtil Insert future description comments Move debug info (source file name) from IrFunction to IrDeclaration
This commit is contained in:
committed by
KonstantinAnisimov
parent
db4388a343
commit
0582d8f1bd
+7
-6
@@ -481,12 +481,13 @@ internal class DeepCopyIrTreeWithDescriptors(val targetDescriptor: FunctionDescr
|
||||
override fun visitBlock(expression: IrBlock): IrBlock {
|
||||
return if (expression is IrReturnableBlock) {
|
||||
IrReturnableBlockImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = expression.type,
|
||||
descriptor = expression.descriptor,
|
||||
origin = mapStatementOrigin(expression.origin),
|
||||
statements = expression.statements.map { it.transform(this, null) }
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = expression.type,
|
||||
descriptor = expression.descriptor,
|
||||
origin = mapStatementOrigin(expression.origin),
|
||||
statements = expression.statements.map { it.transform(this, null) },
|
||||
sourceFileName = expression.sourceFileName
|
||||
)
|
||||
} else {
|
||||
super.visitBlock(expression)
|
||||
|
||||
+2
-1
@@ -40,7 +40,8 @@ open class DeepCopyIrTreeWithReturnableBlockSymbols(
|
||||
expression.startOffset, expression.endOffset,
|
||||
expression.type,
|
||||
expression.descriptor,
|
||||
expression.origin
|
||||
expression.origin,
|
||||
expression.sourceFileName
|
||||
).also {
|
||||
transformedReturnableBlocks.put(expression, it)
|
||||
it.statements.addAll(expression.statements.map { it.transform() })
|
||||
|
||||
+107
-8
@@ -16,8 +16,15 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.util.File
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.SourceManager
|
||||
import org.jetbrains.kotlin.ir.SourceRangeInfo
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlock
|
||||
@@ -26,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBase
|
||||
import org.jetbrains.kotlin.ir.symbols.IrBindableSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrBindableSymbolBase
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
@@ -39,6 +47,7 @@ interface IrReturnableBlockSymbol : IrFunctionSymbol, IrBindableSymbol<FunctionD
|
||||
interface IrReturnableBlock: IrBlock, IrSymbolOwner {
|
||||
override val symbol: IrReturnableBlockSymbol
|
||||
val descriptor: FunctionDescriptor
|
||||
val sourceFileName: String
|
||||
}
|
||||
|
||||
class IrReturnableBlockSymbolImpl(descriptor: FunctionDescriptor) :
|
||||
@@ -46,24 +55,23 @@ class IrReturnableBlockSymbolImpl(descriptor: FunctionDescriptor) :
|
||||
IrReturnableBlockSymbol
|
||||
|
||||
class IrReturnableBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||
override val symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin? = null)
|
||||
override val symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin? = null, override val sourceFileName: String = "no source file")
|
||||
: IrContainerExpressionBase(startOffset, endOffset, type, origin), IrReturnableBlock {
|
||||
|
||||
override val descriptor = symbol.descriptor
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||
symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin?, statements: List<IrStatement>) :
|
||||
this(startOffset, endOffset, type, symbol, origin) {
|
||||
symbol: IrReturnableBlockSymbol, origin: IrStatementOrigin?, statements: List<IrStatement>, sourceFileName: String = "no source file") :
|
||||
this(startOffset, endOffset, type, symbol, origin, sourceFileName) {
|
||||
this.statements.addAll(statements)
|
||||
}
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||
descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null) :
|
||||
this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin)
|
||||
descriptor: FunctionDescriptor, origin: IrStatementOrigin? = null, sourceFileName: String = "no source file") :
|
||||
this(startOffset, endOffset, type, IrReturnableBlockSymbolImpl(descriptor), origin, sourceFileName)
|
||||
|
||||
constructor(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||
descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List<IrStatement>) :
|
||||
this(startOffset, endOffset, type, descriptor, origin) {
|
||||
descriptor: FunctionDescriptor, origin: IrStatementOrigin?, statements: List<IrStatement>, sourceFileName: String = "no source file") :
|
||||
this(startOffset, endOffset, type, descriptor, origin, sourceFileName) {
|
||||
this.statements.addAll(statements)
|
||||
}
|
||||
|
||||
@@ -85,6 +93,97 @@ class IrReturnableBlockImpl(startOffset: Int, endOffset: Int, type: KotlinType,
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
/**
|
||||
* TODO
|
||||
* FileEntry provides mapping file offset to pair line and column which are used in debug information generation.
|
||||
* NaiveSourceBasedFileEntryImpl implements the functionality with calculation lines and columns at compile time,
|
||||
* that obligates user to have sources of all dependencies, that not always possible and intuitively clear. Instead new
|
||||
* version should rely on serialized mapping (offset to pair line and column), which should be generated at library
|
||||
* compilation stage (perhaps in or before inline face)
|
||||
*/
|
||||
|
||||
class NaiveSourceBasedFileEntryImpl(override val name: String) : SourceManager.FileEntry {
|
||||
|
||||
private val lineStartOffsets: IntArray
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
init {
|
||||
val file = File(name)
|
||||
if (file.isFile) {
|
||||
val buffer = mutableListOf<Int>()
|
||||
var currentOffset = 0
|
||||
file.forEachLine { line ->
|
||||
buffer.add(currentOffset)
|
||||
currentOffset += line.length
|
||||
}
|
||||
lineStartOffsets = buffer.toIntArray()
|
||||
} else {
|
||||
lineStartOffsets = IntArray(0)
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun getLineNumber(offset: Int): Int {
|
||||
val index = lineStartOffsets.binarySearch(offset)
|
||||
return if (index >= 0) index else -index - 1
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override fun getColumnNumber(offset: Int): Int {
|
||||
var lineNumber = getLineNumber(offset)
|
||||
if (lineNumber >= lineStartOffsets.size) {
|
||||
lineNumber = lineStartOffsets.size - 1
|
||||
}
|
||||
if (lineNumber < 0) lineNumber = 0
|
||||
if (lineStartOffsets.size == 0) return offset
|
||||
return offset - lineStartOffsets[lineNumber]
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override val maxOffset: Int
|
||||
get() = TODO("not implemented")
|
||||
|
||||
override fun getSourceRangeInfo(beginOffset: Int, endOffset: Int): SourceRangeInfo {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
|
||||
class IrFileImpl(fileName: String) : IrFile {
|
||||
|
||||
override val fileEntry = NaiveSourceBasedFileEntryImpl(fileName)
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
override val fileAnnotations: MutableList<AnnotationDescriptor>
|
||||
get() = TODO("not implemented")
|
||||
override val symbol: IrFileSymbol
|
||||
get() = TODO("not implemented")
|
||||
override val packageFragmentDescriptor: PackageFragmentDescriptor
|
||||
get() = TODO("not implemented")
|
||||
override val endOffset: Int
|
||||
get() = TODO("not implemented")
|
||||
override val startOffset: Int
|
||||
get() = TODO("not implemented")
|
||||
override val declarations: MutableList<IrDeclaration>
|
||||
get() = TODO("not implemented")
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
TODO("not implemented")
|
||||
}
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
TODO("not implemented")
|
||||
}
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
|
||||
TODO("not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
|
||||
interface IrSuspensionPoint : IrExpression {
|
||||
|
||||
+14
-6
@@ -17,17 +17,17 @@
|
||||
package org.jetbrains.kotlin.backend.konan.ir
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
|
||||
class ModuleIndex(val module: IrModuleFragment) {
|
||||
|
||||
var currentFile: IrFile? = null
|
||||
/**
|
||||
* Contains all classes declared in [module]
|
||||
*/
|
||||
@@ -37,6 +37,7 @@ class ModuleIndex(val module: IrModuleFragment) {
|
||||
* Contains all functions declared in [module]
|
||||
*/
|
||||
val functions = mutableMapOf<FunctionDescriptor, IrFunction>()
|
||||
val declarationToFile = mutableMapOf<DeclarationDescriptor, String>()
|
||||
|
||||
init {
|
||||
val map = mutableMapOf<ClassDescriptor, IrClass>()
|
||||
@@ -46,6 +47,11 @@ class ModuleIndex(val module: IrModuleFragment) {
|
||||
element.acceptChildrenVoid(this)
|
||||
}
|
||||
|
||||
override fun visitFile(declaration: IrFile) {
|
||||
currentFile = declaration
|
||||
super.visitFile(declaration)
|
||||
}
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
super.visitClass(declaration)
|
||||
|
||||
@@ -54,11 +60,13 @@ class ModuleIndex(val module: IrModuleFragment) {
|
||||
|
||||
override fun visitFunction(declaration: IrFunction) {
|
||||
super.visitFunction(declaration)
|
||||
|
||||
val functionDescriptor = declaration.descriptor
|
||||
functions[functionDescriptor] = declaration
|
||||
functions[declaration.descriptor] = declaration
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration) {
|
||||
super.visitDeclaration(declaration)
|
||||
declarationToFile[declaration.descriptor] = currentFile!!.name
|
||||
}
|
||||
})
|
||||
|
||||
classes = map
|
||||
|
||||
+2
-4
@@ -24,8 +24,6 @@ import org.jetbrains.kotlin.backend.common.ir.ir2string
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.library.LinkData
|
||||
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter
|
||||
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -1416,7 +1414,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : InnerScopeImpl() {
|
||||
private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlockImpl) : FileScope(IrFileImpl(returnableBlock.sourceFileName)) {
|
||||
|
||||
var bbExit : LLVMBasicBlockRef? = null
|
||||
var resultPhi : LLVMValueRef? = null
|
||||
@@ -1452,7 +1450,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private inner class FileScope(val file:IrFile) : InnerScopeImpl() {
|
||||
private open inner class FileScope(val file:IrFile) : InnerScopeImpl() {
|
||||
override fun fileScope(): CodeContext? = this
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -132,13 +132,15 @@ private class Inliner(val globalSubstituteMap: MutableMap<DeclarationDescriptor,
|
||||
|
||||
val statements = (copyFunctionDeclaration.body as IrBlockBody).statements // IR statements from function copy.
|
||||
val returnType = copyFunctionDeclaration.descriptor.returnType!! // Substituted return type.
|
||||
val sourceFileName = context.ir.originalModuleIndex.declarationToFile[functionDeclaration.descriptor.original]?:""
|
||||
val inlineFunctionBody = IrReturnableBlockImpl( // Create new IR element to replace "call".
|
||||
startOffset = copyFunctionDeclaration.startOffset,
|
||||
endOffset = copyFunctionDeclaration.endOffset,
|
||||
type = returnType,
|
||||
descriptor = copyFunctionDeclaration.descriptor.original,
|
||||
origin = null,
|
||||
statements = statements
|
||||
statements = statements,
|
||||
sourceFileName = sourceFileName
|
||||
)
|
||||
|
||||
val transformer = ParameterSubstitutor()
|
||||
|
||||
+1
@@ -321,6 +321,7 @@ message IrDeclaration {
|
||||
required Coordinates coordinates = 2;
|
||||
required IrDeclarator declarator = 3;
|
||||
repeated IrDeclaration nested = 4;
|
||||
required string file_name = 5;
|
||||
}
|
||||
|
||||
/* ------- IrStatements --------------------------------------------- */
|
||||
|
||||
+5
-2
@@ -512,7 +512,6 @@ internal class IrSerializer(val context: Context,
|
||||
proto.addDefaultArgument(pair)
|
||||
}
|
||||
}
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
|
||||
@@ -638,6 +637,8 @@ internal class IrSerializer(val context: Context,
|
||||
|
||||
|
||||
proto.setDeclarator(declarator)
|
||||
val fileName = context.ir.originalModuleIndex.declarationToFile[declaration.descriptor]
|
||||
proto.setFileName(fileName)
|
||||
|
||||
return proto.build()
|
||||
}
|
||||
@@ -1111,7 +1112,6 @@ internal class IrDeserializer(val context: Context,
|
||||
descriptor.valueParameters.get(it.position),
|
||||
IrExpressionBodyImpl(start, end, expr))
|
||||
}
|
||||
|
||||
return function
|
||||
}
|
||||
|
||||
@@ -1169,6 +1169,9 @@ internal class IrDeserializer(val context: Context,
|
||||
}
|
||||
}
|
||||
|
||||
val sourceFileName = proto.fileName
|
||||
context.ir.originalModuleIndex.declarationToFile[declaration.descriptor.original] = sourceFileName
|
||||
|
||||
if (!(descriptor is VariableDescriptor) && descriptor != rootFunction)
|
||||
localDeserializer.popContext(descriptor)
|
||||
context.log{"### Deserialized declaration: ${ir2string(declaration)}"}
|
||||
|
||||
+1
@@ -59,6 +59,7 @@ class File(val path: String) {
|
||||
fun readBytes() = javaFile.readBytes()
|
||||
fun writeText(text: String) = javaFile.writeText(text)
|
||||
fun writeBytes(bytes: ByteArray) = javaFile.writeBytes(bytes)
|
||||
fun forEachLine(action: (String) -> Unit) { javaFile.forEachLine { action(it) } }
|
||||
|
||||
override fun toString() = path
|
||||
|
||||
|
||||
Reference in New Issue
Block a user