Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure EtsIR is more three-address-like #245

Merged
merged 4 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 29 additions & 33 deletions jacodb-ets/src/main/kotlin/org/jacodb/ets/dto/Convert.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import org.jacodb.ets.base.EtsDivExpr
import org.jacodb.ets.base.EtsEntity
import org.jacodb.ets.base.EtsEqExpr
import org.jacodb.ets.base.EtsExpExpr
import org.jacodb.ets.base.EtsExpr
import org.jacodb.ets.base.EtsFieldRef
import org.jacodb.ets.base.EtsGotoStmt
import org.jacodb.ets.base.EtsGtEqExpr
Expand Down Expand Up @@ -126,7 +127,12 @@ class EtsMethodBuilder(
val etsMethod = EtsMethodImpl(signature, localsCount, modifiers)

private val currentStmts: MutableList<EtsStmt> = mutableListOf()
private var freeLocal: Int = 0

private var freeTempLocal: Int = 0

private fun newTempLocal(type: EtsType): EtsLocal {
return EtsLocal("_tmp${freeTempLocal++}", type)
}

private fun loc(): EtsInstLocation {
return EtsInstLocation(etsMethod, currentStmts.size)
Expand All @@ -142,6 +148,24 @@ class EtsMethodBuilder(
return etsMethod
}

private fun ensureOneAddress(entity: EtsEntity): EtsValue {
// TODO: think about whether 'CastExpr' should be considered "one-address". This would require changing the return type of this function to `EtsEntity`.
// if (entity is EtsCastExpr) return entity

if (entity is EtsExpr || entity is EtsFieldRef || entity is EtsArrayAccess) {
val newLocal = newTempLocal(entity.type)
currentStmts += EtsAssignStmt(
location = loc(),
lhv = newLocal,
rhv = entity,
)
return newLocal
} else {
check(entity is EtsValue)
return entity
}
}

fun convertToEtsStmt(stmt: StmtDto): EtsStmt {
return when (stmt) {
is UnknownStmtDto -> object : EtsStmt {
Expand All @@ -161,7 +185,7 @@ class EtsMethodBuilder(
is AssignStmtDto -> EtsAssignStmt(
location = loc(),
lhv = convertToEtsEntity(stmt.left) as EtsValue,
rhv = convertToEtsEntity(stmt.right),
rhv = ensureOneAddress(convertToEtsEntity(stmt.right)),
)

is CallStmtDto -> EtsCallStmt(
Expand All @@ -170,21 +194,9 @@ class EtsMethodBuilder(
)

is ReturnStmtDto -> {
val etsEntity = convertToEtsEntity(stmt.arg)
val etsValue = if (etsEntity is EtsValue) {
etsEntity
} else {
val newLocal = EtsLocal("_tmp${freeLocal++}", EtsUnknownType)
currentStmts += EtsAssignStmt(
location = loc(),
lhv = newLocal,
rhv = etsEntity,
)
newLocal
}
EtsReturnStmt(
location = loc(),
returnValue = etsValue,
returnValue = ensureOneAddress(convertToEtsEntity(stmt.arg)),
)
}

Expand Down Expand Up @@ -353,30 +365,14 @@ class EtsMethodBuilder(
instance = convertToEtsEntity(value.instance),
method = convertToEtsMethodSignature(value.method),
args = value.args.map {
val etsEntity = convertToEtsEntity(it)
if (etsEntity is EtsValue) return@map etsEntity
val newLocal = EtsLocal("_tmp${freeLocal++}", EtsUnknownType)
currentStmts += EtsAssignStmt(
location = loc(),
lhv = newLocal,
rhv = etsEntity,
)
newLocal
ensureOneAddress(convertToEtsEntity(it))
},
)

is StaticCallExprDto -> EtsStaticCallExpr(
method = convertToEtsMethodSignature(value.method),
args = value.args.map {
val etsEntity = convertToEtsEntity(it)
if (etsEntity is EtsValue) return@map etsEntity
val newLocal = EtsLocal("_tmp${freeLocal++}", EtsUnknownType)
currentStmts += EtsAssignStmt(
location = loc(),
lhv = newLocal,
rhv = etsEntity,
)
newLocal
ensureOneAddress(convertToEtsEntity(it))
},
)

Expand Down
8 changes: 4 additions & 4 deletions jacodb-ets/src/test/kotlin/org/jacodb/ets/test/EtsFileTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ class EtsFileTest {
fun `test etsFile on TypeMismatch`() {
val etsFile = load("etsir/samples/TypeMismatch")
etsFile.classes.forEach { cls ->
cls.methods.forEach { etsMethod ->
when (etsMethod.name) {
cls.methods.forEach { method ->
when (method.name) {
"add" -> {
Assertions.assertEquals(9, etsMethod.cfg.instructions.size)
Assertions.assertEquals(11, method.cfg.instructions.size)
}

"main" -> {
Assertions.assertEquals(4, etsMethod.cfg.instructions.size)
Assertions.assertEquals(5, method.cfg.instructions.size)
}
}
}
Expand Down
Loading