translator: refactor variable allocation
This commit is contained in:
+8
-4
@@ -7,11 +7,15 @@ lightRed = '\033[1;31m'
|
|||||||
orange = '\033[0;33m'
|
orange = '\033[0;33m'
|
||||||
nc = '\033[0m'
|
nc = '\033[0m'
|
||||||
|
|
||||||
|
stdlib:
|
||||||
|
cd ../kotstd && make clean && make
|
||||||
|
|
||||||
%.out: %.txt
|
%.out: stdlib %.txt
|
||||||
@./run_one_test.sh $(@:.out=.txt)
|
@./run_one_test.sh $(@:.out=.txt)
|
||||||
|
|
||||||
all: $(OBJECTS)
|
tests: stdlib $(OBJECTS)
|
||||||
@echo "ok"
|
@date
|
||||||
|
|
||||||
.PHONY: all
|
.DEFAULT_GOAL := tests
|
||||||
|
|
||||||
|
.PHONY: tests, stdlib
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
if (result.pointer == 1 && result.type !is LLVMReferenceType) {
|
if (result.pointer == 1 && result.type !is LLVMReferenceType) {
|
||||||
result = codeBuilder.loadAndGetVariable(result)
|
result = codeBuilder.loadAndGetVariable(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.type is LLVMReferenceType) {
|
if (result.type is LLVMReferenceType) {
|
||||||
genReferenceReturn(result)
|
genReferenceReturn(result)
|
||||||
} else {
|
} else {
|
||||||
@@ -119,7 +118,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
fun evaluateConstructorDelegationReferenceExpression(expr: KtConstructorDelegationReferenceExpression, structCodegen: StructCodegen, constructorArguments: List<LLVMVariable>, scopeDepth: Int): LLVMSingleValue? {
|
fun evaluateConstructorDelegationReferenceExpression(expr: KtConstructorDelegationReferenceExpression, structCodegen: StructCodegen, constructorArguments: List<LLVMVariable>, scopeDepth: Int): LLVMSingleValue? {
|
||||||
val targetCall = state.bindingContext.get(BindingContext.CALL, expr)
|
val targetCall = state.bindingContext.get(BindingContext.CALL, expr)
|
||||||
|
|
||||||
val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth)
|
val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth)
|
||||||
val args = codeBuilder.loadArgsIfRequired(names, constructorArguments)
|
val args = codeBuilder.loadArgsIfRequired(names, constructorArguments)
|
||||||
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.fullName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
|
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.fullName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
|
||||||
@@ -157,9 +155,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
expectedType.prefix = "class"
|
expectedType.prefix = "class"
|
||||||
}
|
}
|
||||||
|
|
||||||
val result = codeBuilder.getNewVariable(expectedType, pointer = 1)
|
val result = codeBuilder.getNewVariable(expectedType, pointer = 2)
|
||||||
codeBuilder.allocStaticVar(result)
|
codeBuilder.allocStaticVar(result, pointer = true)
|
||||||
result.pointer++
|
|
||||||
|
|
||||||
val condition = left.type!!.operatorEq(loadedLeft, LLVMVariable("", LLVMNullType()))
|
val condition = left.type!!.operatorEq(loadedLeft, LLVMVariable("", LLVMNullType()))
|
||||||
val thenLabel = codeBuilder.getNewLabel(prefix = "safe.access")
|
val thenLabel = codeBuilder.getNewLabel(prefix = "safe.access")
|
||||||
@@ -168,8 +165,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
val conditionResult = codeBuilder.getNewVariable(condition.variableType)
|
val conditionResult = codeBuilder.getNewVariable(condition.variableType)
|
||||||
codeBuilder.addAssignment(conditionResult, condition)
|
codeBuilder.addAssignment(conditionResult, condition)
|
||||||
|
|
||||||
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
||||||
|
|
||||||
codeBuilder.markWithLabel(thenLabel)
|
codeBuilder.markWithLabel(thenLabel)
|
||||||
codeBuilder.storeNull(result)
|
codeBuilder.storeNull(result)
|
||||||
codeBuilder.addUnconditionalJump(endLabel)
|
codeBuilder.addUnconditionalJump(endLabel)
|
||||||
@@ -201,7 +198,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
is KtBinaryExpression -> evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
is KtBinaryExpression -> evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
||||||
is KtDotQualifiedExpression -> {
|
is KtDotQualifiedExpression -> {
|
||||||
val codegen = resolveCodegenByName(receiverName, receiverName.split("."))
|
val codegen = resolveCodegenByName(receiverName, receiverName.split("."))
|
||||||
|
|
||||||
if (codegen != null) null else evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
if (codegen != null) null else evaluateExpression(receiverExpr, scopeDepth) as LLVMVariable
|
||||||
}
|
}
|
||||||
is KtNameReferenceExpression -> {
|
is KtNameReferenceExpression -> {
|
||||||
@@ -251,19 +247,20 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
val targetFunction = state.bindingContext.get(BindingContext.CALL, selector.calleeExpression)
|
val targetFunction = state.bindingContext.get(BindingContext.CALL, selector.calleeExpression)
|
||||||
val resolvedCall = state.bindingContext.get(BindingContext.RESOLVED_CALL, targetFunction)
|
val resolvedCall = state.bindingContext.get(BindingContext.RESOLVED_CALL, targetFunction)
|
||||||
val targetFunctionName = resolvedCall!!.candidateDescriptor.fqNameSafe.asString().removeSuffix(".<init>")
|
val targetFunctionName = resolvedCall!!.candidateDescriptor.fqNameSafe.convertToNativeName()
|
||||||
val nameWithoutMangling = resolvedCall.candidateDescriptor.name.asString().replace(Regex("""(.?)<init>"""), "")
|
val nameWithoutMangling = resolvedCall.candidateDescriptor.name.asString().replace(Regex("""(.?)<init>"""), "")
|
||||||
val packageNameFirst = targetFunction?.calleeExpression?.getContainingKtFile()?.packageFqName?.asString()?.removeSuffix(".<init>") ?: ""
|
val packageNameFirst = targetFunction?.calleeExpression?.getContainingKtFile()?.packageFqName?.convertToNativeName() ?: ""
|
||||||
val packageNameSecond = resolvedCall.candidateDescriptor.containingDeclaration.fqNameSafe.asString().removeSuffix(".<init>")
|
val packageNameSecond = resolvedCall.candidateDescriptor.containingDeclaration.fqNameSafe.convertToNativeName()
|
||||||
|
|
||||||
val names = parseArgList(selector, scopeDepth)
|
val names = parseArgList(selector, scopeDepth)
|
||||||
val type = if (names.size > 0) LLVMType.mangleFunctionArguments(names) else ""
|
val type = if (names.size > 0) LLVMType.mangleFunctionArguments(names) else ""
|
||||||
|
|
||||||
val constructedFunctionName = standardType.mangle() + nameWithoutMangling.addBeforeIfNotEmpty(".") + type
|
val constructedFunctionName = standardType.mangle() + nameWithoutMangling.addBeforeIfNotEmpty(".") + type
|
||||||
|
val targetExtension = state.extensionFunctions[standardType.toString()]
|
||||||
|
|
||||||
val extensionCodegen = state.extensionFunctions[standardType.toString()]?.get(packageNameFirst.addAfterIfNotEmpty(".") + constructedFunctionName) ?:
|
val extensionCodegen = targetExtension?.get(packageNameFirst.addAfterIfNotEmpty(".") + constructedFunctionName) ?:
|
||||||
state.extensionFunctions[standardType.toString()]?.get(packageNameSecond.addAfterIfNotEmpty(".") + constructedFunctionName) ?:
|
targetExtension?.get(packageNameSecond.addAfterIfNotEmpty(".") + constructedFunctionName) ?:
|
||||||
state.extensionFunctions[standardType.toString()]?.get(targetFunctionName)
|
targetExtension?.get(targetFunctionName)
|
||||||
?: throw UnexpectedException(constructedFunctionName)
|
?: throw UnexpectedException(constructedFunctionName)
|
||||||
val receiverExpression = receiverExpressionArgument ?: evaluateExpression(receiver, scopeDepth + 1)!!
|
val receiverExpression = receiverExpressionArgument ?: evaluateExpression(receiver, scopeDepth + 1)!!
|
||||||
|
|
||||||
@@ -373,7 +370,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? {
|
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: StructCodegen? = null): LLVMSingleValue? {
|
||||||
val targetName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)?.fqNameSafe?.asString()?.replace(".<init>", "")
|
val targetName = state.bindingContext.get(BindingContext.REFERENCE_TARGET, expr)?.fqNameSafe?.convertToNativeName()
|
||||||
return when {
|
return when {
|
||||||
expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
expr is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
||||||
isEnumClassField(expr, classScope) -> resolveEnumClassField(expr, classScope)
|
isEnumClassField(expr, classScope) -> resolveEnumClassField(expr, classScope)
|
||||||
@@ -438,7 +435,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
if (resolvedCall is VariableAsFunctionResolvedCallImpl) {
|
if (resolvedCall is VariableAsFunctionResolvedCallImpl) {
|
||||||
resolvedCall = resolvedCall.variableCall
|
resolvedCall = resolvedCall.variableCall
|
||||||
}
|
}
|
||||||
val targetFunctionName = resolvedCall!!.candidateDescriptor.fqNameSafe.asString().removeSuffix(".<init>")
|
|
||||||
|
val targetFunctionName = resolvedCall!!.candidateDescriptor.fqNameSafe.convertToNativeName()
|
||||||
val functionDescriptor = expr.getFunctionResolvedCallWithAssert(state.bindingContext).candidateDescriptor
|
val functionDescriptor = expr.getFunctionResolvedCallWithAssert(state.bindingContext).candidateDescriptor
|
||||||
val arguments = resolvedCall.valueArguments.toSortedMap(compareBy { it.index }).values
|
val arguments = resolvedCall.valueArguments.toSortedMap(compareBy { it.index }).values
|
||||||
|
|
||||||
@@ -530,9 +528,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
codeBuilder.addLLVMCode(LLVMCall(LLVMVoidType(), function.toString(), names).toString())
|
codeBuilder.addLLVMCode(LLVMCall(LLVMVoidType(), function.toString(), names).toString())
|
||||||
}
|
}
|
||||||
is LLVMReferenceType -> {
|
is LLVMReferenceType -> {
|
||||||
val returnVar = codeBuilder.getNewVariable(returnType, pointer = 1)
|
val returnVar = codeBuilder.getNewVariable(returnType, pointer = 2)
|
||||||
codeBuilder.allocStaticVar(returnVar)
|
codeBuilder.allocStaticVar(returnVar, pointer = true)
|
||||||
returnVar.pointer++
|
|
||||||
|
|
||||||
val args = ArrayList<LLVMSingleValue>()
|
val args = ArrayList<LLVMSingleValue>()
|
||||||
args.add(returnVar)
|
args.add(returnVar)
|
||||||
@@ -549,9 +546,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
val result = codeBuilder.getNewVariable(returnType)
|
val result = codeBuilder.getNewVariable(returnType)
|
||||||
codeBuilder.addAssignment(result, LLVMCall(returnType, function.toString(), names))
|
codeBuilder.addAssignment(result, LLVMCall(returnType, function.toString(), names))
|
||||||
|
|
||||||
val resultPtr = codeBuilder.getNewVariable(returnType)
|
val resultPtr = codeBuilder.getNewVariable(returnType, pointer = 1)
|
||||||
codeBuilder.allocStackVar(resultPtr)
|
codeBuilder.allocStackVar(resultPtr, pointer = true)
|
||||||
resultPtr.pointer = 1
|
|
||||||
codeBuilder.storeVariable(resultPtr, result)
|
codeBuilder.storeVariable(resultPtr, result)
|
||||||
return resultPtr
|
return resultPtr
|
||||||
}
|
}
|
||||||
@@ -561,14 +557,11 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateConstructorCallExpression(function: LLVMVariable, names: List<LLVMSingleValue>): LLVMSingleValue? {
|
private fun evaluateConstructorCallExpression(function: LLVMVariable, names: List<LLVMSingleValue>): LLVMSingleValue? {
|
||||||
val store = codeBuilder.getNewVariable(function.type)
|
val store = codeBuilder.getNewVariable(function.type, pointer = 1)
|
||||||
codeBuilder.allocStaticVar(store)
|
codeBuilder.allocStaticVar(store, pointer = true)
|
||||||
store.pointer++
|
|
||||||
|
|
||||||
val result = codeBuilder.getNewVariable(function.type, pointer = 1)
|
|
||||||
codeBuilder.allocStackVar(result)
|
|
||||||
result.pointer++
|
|
||||||
|
|
||||||
|
val result = codeBuilder.getNewVariable(function.type, pointer = 2)
|
||||||
|
codeBuilder.allocStackVar(result, pointer = true)
|
||||||
codeBuilder.storeVariable(result, store)
|
codeBuilder.storeVariable(result, store)
|
||||||
|
|
||||||
val args = ArrayList<LLVMSingleValue>()
|
val args = ArrayList<LLVMSingleValue>()
|
||||||
@@ -595,6 +588,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
for (arg in args) {
|
for (arg in args) {
|
||||||
result.add(parseOneValueArgument(arg, scopeDepth))
|
result.add(parseOneValueArgument(arg, scopeDepth))
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,6 +610,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable? {
|
||||||
val operator = expr.operationToken
|
val operator = expr.operationToken
|
||||||
|
|
||||||
if (operator == KtTokens.ELVIS) {
|
if (operator == KtTokens.ELVIS) {
|
||||||
return evaluateElvisOperator(expr, scopeDepth)
|
return evaluateElvisOperator(expr, scopeDepth)
|
||||||
}
|
}
|
||||||
@@ -628,20 +623,24 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
left ?: throw UnsupportedOperationException("Wrong binary exception: ${expr.text}")
|
left ?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}")
|
||||||
val right = evaluateExpression(expr.right, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception: ${expr.text}")
|
val right = evaluateExpression(expr.right, scopeDepth)
|
||||||
|
?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}")
|
||||||
|
|
||||||
return executeBinaryExpression(operator, expr.operationReference, left, right)
|
return executeBinaryExpression(operator, expr.operationReference, left, right)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluatePostfixExpression(expr: KtPostfixExpression, scopeDepth: Int): LLVMSingleValue? {
|
private fun evaluatePostfixExpression(expr: KtPostfixExpression, scopeDepth: Int): LLVMSingleValue? {
|
||||||
val operator = expr.operationToken
|
val operator = expr.operationToken
|
||||||
val left = evaluateExpression(expr.baseExpression, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception: ${expr.text}")
|
val left = evaluateExpression(expr.baseExpression, scopeDepth)
|
||||||
|
?: throw UnsupportedOperationException("Wrong binary expression: ${expr.text}")
|
||||||
return executePostfixExpression(operator, left as LLVMVariable)
|
return executePostfixExpression(operator, left as LLVMVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluatePrefixExpression(expr: KtPrefixExpression, scopeDepth: Int): LLVMSingleValue? {
|
private fun evaluatePrefixExpression(expr: KtPrefixExpression, scopeDepth: Int): LLVMSingleValue? {
|
||||||
val operator = expr.operationToken
|
val operator = expr.operationToken
|
||||||
val left = evaluateExpression(expr.baseExpression, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
val left = evaluateExpression(expr.baseExpression, scopeDepth)
|
||||||
|
?: throw UnsupportedOperationException("Wrong binary expression")
|
||||||
return executePrefixExpression(operator, expr.operationReference, left)
|
return executePrefixExpression(operator, expr.operationReference, left)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +712,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
= addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||||
|
|
||||||
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
||||||
val left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
val left = evaluateExpression(expr.firstChild, scopeDepth)
|
||||||
|
?: throw UnsupportedOperationException("Wrong binary expression")
|
||||||
val lptr = codeBuilder.loadAndGetVariable(left as LLVMVariable)
|
val lptr = codeBuilder.loadAndGetVariable(left as LLVMVariable)
|
||||||
|
|
||||||
val condition = lptr.type.operatorEq(lptr, LLVMVariable("", LLVMNullType()))
|
val condition = lptr.type.operatorEq(lptr, LLVMVariable("", LLVMNullType()))
|
||||||
@@ -726,7 +726,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
val endLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
val endLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
||||||
|
|
||||||
codeBuilder.addCondition(conditionResult, elseLabel, thenLabel)
|
codeBuilder.addCondition(conditionResult, elseLabel, thenLabel)
|
||||||
|
|
||||||
codeBuilder.markWithLabel(thenLabel)
|
codeBuilder.markWithLabel(thenLabel)
|
||||||
codeBuilder.addUnconditionalJump(endLabel)
|
codeBuilder.addUnconditionalJump(endLabel)
|
||||||
|
|
||||||
@@ -738,8 +737,8 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
}
|
}
|
||||||
|
|
||||||
codeBuilder.addUnconditionalJump(endLabel)
|
codeBuilder.addUnconditionalJump(endLabel)
|
||||||
|
|
||||||
codeBuilder.markWithLabel(endLabel)
|
codeBuilder.markWithLabel(endLabel)
|
||||||
|
|
||||||
return left
|
return left
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,16 +880,16 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
return firstOp
|
return firstOp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val result = firstOp as LLVMVariable
|
val result = firstOp as LLVMVariable
|
||||||
val sourceArgument: LLVMSingleValue
|
val sourceArgument: LLVMSingleValue
|
||||||
if (secondOp.type!!.isPrimitive() && (secondOp.pointer == 0) && (firstOp.pointer == 2)) {
|
if (secondOp.type!!.isPrimitive() && (secondOp.pointer == 0) && (firstOp.pointer == 2)) {
|
||||||
sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1)
|
sourceArgument = codeBuilder.getNewVariable(secondOp.type!!, 1)
|
||||||
codeBuilder.allocStaticVar(sourceArgument, true)
|
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
|
||||||
codeBuilder.storeVariable(sourceArgument, secondOp)
|
codeBuilder.storeVariable(sourceArgument, secondOp)
|
||||||
} else {
|
} else {
|
||||||
sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
|
sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
|
||||||
}
|
}
|
||||||
|
|
||||||
codeBuilder.storeVariable(result, sourceArgument)
|
codeBuilder.storeVariable(result, sourceArgument)
|
||||||
codeBuilder.addComment("end variable assignment")
|
codeBuilder.addComment("end variable assignment")
|
||||||
return result
|
return result
|
||||||
@@ -960,11 +959,9 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
val loopParameter = state.bindingContext.get(BindingContext.VALUE_PARAMETER, expr.loopParameter!!)?.fqNameSafe?.asString() ?: expr.loopParameter!!.name!!
|
val loopParameter = state.bindingContext.get(BindingContext.VALUE_PARAMETER, expr.loopParameter!!)?.fqNameSafe?.asString() ?: expr.loopParameter!!.name!!
|
||||||
|
|
||||||
val allocVar = variableManager.receiveVariable(loopParameter, nextDescriptor.returnType!!.type, LLVMRegisterScope(), pointer =
|
val allocVar = variableManager.receiveVariable(loopParameter, nextDescriptor.returnType!!.type, LLVMRegisterScope(), pointer =
|
||||||
nextDescriptor.returnType!!.pointer)
|
nextDescriptor.returnType!!.pointer+1)
|
||||||
variableManager.addVariable(loopParameter, allocVar, scopeDepth + 1)
|
variableManager.addVariable(loopParameter, allocVar, scopeDepth + 1)
|
||||||
codeBuilder.allocStackVar(allocVar)
|
codeBuilder.allocStackVar(allocVar, pointer = true)
|
||||||
allocVar.pointer++
|
|
||||||
allocVar.kotlinName = loopParameter
|
|
||||||
|
|
||||||
addPrimitiveBinaryOperation(KtTokens.EQ, null, allocVar, currentParameter)
|
addPrimitiveBinaryOperation(KtTokens.EQ, null, allocVar, currentParameter)
|
||||||
|
|
||||||
@@ -1128,17 +1125,15 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
|
|||||||
|
|
||||||
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateValExpression(element: KtProperty, scopeDepth: Int): LLVMVariable? {
|
||||||
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
|
val variable = state.bindingContext.get(BindingContext.VARIABLE, element)!!
|
||||||
val identifier = variable.fqNameSafe.asString().replace(".<init>", "")
|
val identifier = variable.fqNameSafe.convertToNativeName()
|
||||||
|
|
||||||
val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth)
|
val assignExpression = evaluateExpression(element.delegateExpressionOrInitializer, scopeDepth)
|
||||||
val expectedExpressionType = LLVMInstanceOfStandardType("", variable.type, state = state)
|
val expectedExpressionType = LLVMInstanceOfStandardType("", variable.type, state = state)
|
||||||
|
|
||||||
val primitivePointer = LLVMMapStandardType(variable.type, state) !is LLVMReferred
|
val primitivePointer = LLVMMapStandardType(variable.type, state) !is LLVMReferred
|
||||||
|
|
||||||
val allocVar = variableManager.receiveVariable(identifier, expectedExpressionType.type, LLVMRegisterScope(), pointer = expectedExpressionType.pointer)
|
val allocVar = variableManager.receiveVariable(identifier, expectedExpressionType.type, LLVMRegisterScope(), pointer = expectedExpressionType.pointer+1)
|
||||||
codeBuilder.allocStackVar(allocVar)
|
codeBuilder.allocStackVar(allocVar, pointer = true)
|
||||||
allocVar.pointer++
|
|
||||||
allocVar.kotlinName = identifier
|
|
||||||
|
|
||||||
variableManager.addVariable(identifier, allocVar, scopeDepth)
|
variableManager.addVariable(identifier, allocVar, scopeDepth)
|
||||||
if (assignExpression != null) {
|
if (assignExpression != null) {
|
||||||
|
|||||||
@@ -69,4 +69,3 @@ class ProjectTranslator(val files: List<KtFile>, val state: TranslationState) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ abstract class StructCodegen(val state: TranslationState,
|
|||||||
variableManager.addVariable("this", classVal, 0)
|
variableManager.addVariable("this", classVal, 0)
|
||||||
|
|
||||||
val secondaryConstructorArguments = descriptor!!.valueParameters.map {
|
val secondaryConstructorArguments = descriptor!!.valueParameters.map {
|
||||||
LLVMInstanceOfStandardType(it.fqNameSafe.asString().replace(".<init>", ""), it.type, state = state)
|
LLVMInstanceOfStandardType(it.fqNameSafe.convertToNativeName(), it.type, state = state)
|
||||||
}
|
}
|
||||||
|
|
||||||
argFields.add(classVal)
|
argFields.add(classVal)
|
||||||
@@ -222,7 +222,7 @@ abstract class StructCodegen(val state: TranslationState,
|
|||||||
|
|
||||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||||
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||||
codeBuilder.addComment("field initilizers starts")
|
codeBuilder.addComment("field initializers starts")
|
||||||
variableManager.addVariable("this", receiverThis, 2)
|
variableManager.addVariable("this", receiverThis, 2)
|
||||||
|
|
||||||
for ((variable, initializer) in initializedFields) {
|
for ((variable, initializer) in initializedFields) {
|
||||||
@@ -235,7 +235,7 @@ abstract class StructCodegen(val state: TranslationState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
variableManager.pullOneUpwardLevelVariable("this")
|
variableManager.pullOneUpwardLevelVariable("this")
|
||||||
codeBuilder.addComment("field initilizers ends")
|
codeBuilder.addComment("field initializers ends")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateReturn(src: LLVMVariable) {
|
private fun generateReturn(src: LLVMVariable) {
|
||||||
@@ -249,7 +249,7 @@ abstract class StructCodegen(val state: TranslationState,
|
|||||||
|
|
||||||
protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType): LLVMClassVariable {
|
protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType): LLVMClassVariable {
|
||||||
val annotations = parseFieldAnnotations(field)
|
val annotations = parseFieldAnnotations(field)
|
||||||
val fieldName = state.bindingContext.get(BindingContext.VALUE_PARAMETER, field as?KtParameter)?.fqNameSafe?.asString()?.replace(".<init>", "")
|
val fieldName = state.bindingContext.get(BindingContext.VALUE_PARAMETER, field as?KtParameter)?.fqNameSafe?.convertToNativeName()
|
||||||
?: field.fqName?.asString() ?: field.name!!
|
?: field.fqName?.asString() ?: field.name!!
|
||||||
|
|
||||||
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
object UniqueGenerator {
|
object UniqueGenerator {
|
||||||
private var unique = 0
|
private var unique = 0
|
||||||
fun generateUniqueString(): String {
|
fun generateUniqueString(): String {
|
||||||
unique += 1
|
unique++
|
||||||
return ".unique." + unique
|
return ".unique." + unique
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,11 +66,12 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
localCode.appendln("}")
|
localCode.appendln("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue = when (firstOp) {
|
fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue =
|
||||||
is LLVMConstant -> firstOp
|
when (firstOp) {
|
||||||
is LLVMVariable -> if (firstOp.pointer == 0) firstOp else loadAndGetVariable(firstOp)
|
is LLVMConstant -> firstOp
|
||||||
else -> throw UnsupportedOperationException()
|
is LLVMVariable -> if (firstOp.pointer == 0) firstOp else loadAndGetVariable(firstOp)
|
||||||
}
|
else -> throw UnsupportedOperationException()
|
||||||
|
}
|
||||||
|
|
||||||
fun loadArgsIfRequired(names: List<LLVMSingleValue>, args: List<LLVMVariable>) =
|
fun loadArgsIfRequired(names: List<LLVMSingleValue>, args: List<LLVMVariable>) =
|
||||||
names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue {
|
names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue {
|
||||||
@@ -157,10 +158,6 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
localCode.appendln("${label.label}:")
|
localCode.appendln("${label.label}:")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addNopInstruction() {
|
|
||||||
localCode.appendln(getNewVariable(LLVMIntType()).toString() + " = add i1 0, 0 ; nop instruction")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
|
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
|
||||||
if ((source.type is LLVMStringType) && (!(source.type as LLVMStringType).isLoaded)) {
|
if ((source.type is LLVMStringType) && (!(source.type as LLVMStringType).isLoaded)) {
|
||||||
storeString(target as LLVMVariable, source as LLVMVariable, 0)
|
storeString(target as LLVMVariable, source as LLVMVariable, 0)
|
||||||
@@ -220,18 +217,19 @@ class LLVMBuilder(val arm: Boolean = false) {
|
|||||||
localCode.appendln(code)
|
localCode.appendln(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false) {
|
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
|
||||||
localCode.appendln("$target = alloca ${if (asValue) target.type.toString() else target.getType()}, align ${target.type.align}")
|
val type = if (asValue) target.type.toString() else target.getType()
|
||||||
|
localCode.appendln("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false) {
|
fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
|
||||||
val allocated = getNewVariable(LLVMCharType(), pointer = 1)
|
val allocated = getNewVariable(LLVMCharType(), pointer = 1)
|
||||||
|
|
||||||
val size = if (target.pointer > 0) TranslationState.pointerSize else target.type.size
|
val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.pointerSize else target.type.size
|
||||||
val alloc = "$allocated = call i8* @malloc_heap(i32 $size)"
|
val alloc = "$allocated = call i8* @malloc_heap(i32 $size)"
|
||||||
localCode.appendln(alloc)
|
localCode.appendln(alloc)
|
||||||
|
|
||||||
val cast = "$target = bitcast ${allocated.getType()} $allocated to ${if (asValue) target.type.toString() else target.getType()}*"
|
val cast = "$target = bitcast ${allocated.getType()} $allocated to ${if (asValue) target.type.toString() else target.getType()}" + if (pointer) "" else "*"
|
||||||
localCode.appendln(cast)
|
localCode.appendln(cast)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.kotlinnative.translator.llvm
|
|||||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
|
import org.jetbrains.kotlin.cfg.pseudocode.getSubtypesPredicate
|
||||||
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
import org.jetbrains.kotlin.js.descriptorUtils.nameIfStandardType
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
@@ -52,10 +53,13 @@ fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope
|
|||||||
fun LLVMMapStandardType(type: KotlinType, state: TranslationState): LLVMType =
|
fun LLVMMapStandardType(type: KotlinType, state: TranslationState): LLVMType =
|
||||||
LLVMInstanceOfStandardType("type", type, LLVMRegisterScope(), state).type
|
LLVMInstanceOfStandardType("type", type, LLVMRegisterScope(), state).type
|
||||||
|
|
||||||
fun String.addBeforeIfNotEmpty(add: String): String {
|
fun String.addBeforeIfNotEmpty(add: String): String =
|
||||||
return if (this.length > 0) add + this else this
|
if (this.length > 0) add + this else this
|
||||||
}
|
|
||||||
|
|
||||||
fun String.addAfterIfNotEmpty(add: String): String {
|
|
||||||
return if (this.length > 0) this + add else this
|
fun String.addAfterIfNotEmpty(add: String): String =
|
||||||
}
|
if (this.length > 0) this + add else this
|
||||||
|
|
||||||
|
|
||||||
|
fun FqName.convertToNativeName(): String =
|
||||||
|
this.asString().replace(".<init>", "")
|
||||||
@@ -15,9 +15,11 @@ fun bytearray_1_array(): Int {
|
|||||||
}
|
}
|
||||||
val newInstance = z.clone()
|
val newInstance = z.clone()
|
||||||
ind = 0
|
ind = 0
|
||||||
|
var result = true
|
||||||
while(ind < size){
|
while(ind < size){
|
||||||
assert(newInstance[ind] == ind.toByte())
|
result = result and (newInstance[ind] == ind.toByte())
|
||||||
ind += 1
|
ind += 1
|
||||||
}
|
}
|
||||||
|
assert(result)
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user