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

Support static fields #261

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Support static fields #261

wants to merge 5 commits into from

Conversation

Lipen
Copy link
Member

@Lipen Lipen commented Feb 19, 2025

This PR adds support for static fields.

Currently, this is just a (partial) copy of Jc-impl.

@Lipen Lipen marked this pull request as ready for review February 24, 2025 13:05
@Lipen Lipen requested a review from CaelmBleidd February 24, 2025 13:05
Copy link
Member

@CaelmBleidd CaelmBleidd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issues with field usage in lvalues and processing of unresolved sorts

private val staticFieldReadings = mkAstInterner<TsStaticFieldReading<*>>()
fun <Sort : USort> mkStaticFieldReading(
regionId: TsStaticFieldRegionId<Sort>,
field: EtsFieldSignature,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fieldSignature might be confusing due to type usage in it

) : UComposer<EtsType, TsSizeSort>(ctx, memory, ownership), TsTransformer
) : UComposer<EtsType, TsSizeSort>(ctx, memory, ownership), TsTransformer {
override fun <Sort : USort> transform(expr: TsStaticFieldReading<Sort>): UExpr<Sort> {
return memory.read(TsStaticFieldLValue(expr.field, expr.sort))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's create util methods for these field values consturctors, that will create lValue from fields' name


fun translate(expr: TsStaticFieldReading<Sort>): UExpr<Sort> =
translated.getOrPut(expr.field) {
expr.sort.mkConst("${expr.field.enclosingClass}_${regionId.sort}_${expr.field.name}")
Copy link
Member

@CaelmBleidd CaelmBleidd Feb 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

usage of enclosing class seems suspicious here since it if often unk/unk, so many fields will be conflicting

override fun read(key: TsStaticFieldLValue<Sort>): UExpr<Sort> {
val translated = translatedFields[key.field]
?: translator.translate(
key.sort.tctx.mkStaticFieldReading(key.memoryRegionId as TsStaticFieldRegionId, key.field, key.sort)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

again, usage of fields should be considered as suspicious

}

val fieldType = scene.fieldLookUp(value.field).type
val sort = typeToSort(fieldType)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if sort is unresolved, so we need to process using fake objects somehow

Comment on lines 175 to 226
val instance = exprResolver.resolve(lhv.instance)?.asExpr(addressSort) ?: return@doWithState
val field = lhv.field
val fieldType = scene.fieldLookUp(field).type
val sort = typeToSort(fieldType)
val lValue = UFieldLValue(sort, instance, field.name)
memory.write(lValue, expr.asExpr(lValue.sort), guard = trueExpr)
}

is EtsStaticFieldRef -> {
val field = lhv.field
val fieldType = scene.fieldLookUp(field).type
val sort = typeToSort(fieldType)
val lValue = TsStaticFieldLValue(field, sort)
memory.write(lValue, expr.asExpr(lValue.sort), guard = trueExpr)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issued with field and unresolved sort

Comment on lines 237 to 258
localVarToIdx.getOrPut(method) {
method.getDeclaredLocals().mapIndexed { idx, local ->
local.name to idx + method.parametersWithThisCount
}.toMap()
}[local.name]
?: error("Local not declared: $local")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting, lets extract something into variables

class TsStaticFieldReading<Sort : USort> internal constructor(
ctx: TsContext,
val regionId: TsStaticFieldRegionId<Sort>,
val field: EtsFieldSignature,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should replace signature with name or how to process it correctly?

@Lipen Lipen force-pushed the lipen/ts-static branch 2 times, most recently from 58c8dee to 3579c90 Compare February 27, 2025 11:03
val clazz = classes.single()
return clazz.fields.single { it.name == field.name }
}
val fields = classes.flatMap { it.fields.filter { it.name == field.name } }

Check warning

Code scanning / detekt

Disallow shadowing variable declarations. Warning

Name shadowed: implicit lambda parameter 'it'
val clazz = classes.single()
return clazz.fields.single { it.name == field.name }
}
val fields = classes.flatMap { it.fields.filter { it.name == field.name } }

Check warning

Code scanning / detekt

Disallow shadowing variable declarations. Warning

Name shadowed: implicit lambda parameter 'it'
}
}

val fields = ctx.scene.projectAndSdkClasses.flatMap { it.fields.filter { it.name == field.name } }

Check warning

Code scanning / detekt

Disallow shadowing variable declarations. Warning

Name shadowed: implicit lambda parameter 'it'
@Lipen Lipen marked this pull request as draft February 28, 2025 12:20
@Lipen Lipen marked this pull request as ready for review February 28, 2025 13:18
}

internal fun TsState.isInitialized(clazz: EtsClass): Boolean {
val instance = staticStorage[clazz]!!

Check warning

Code scanning / detekt

Unsafe calls on nullable types detected. These calls will throw a NullPointerException in case the nullable value is null. Warning

Calling !! on a nullable type will throw a NullPointerException at runtime in case the value is null. It should be avoided.
}

internal fun TsState.markInitialized(clazz: EtsClass) {
val instance = staticStorage[clazz]!!

Check warning

Code scanning / detekt

Unsafe calls on nullable types detected. These calls will throw a NullPointerException in case the nullable value is null. Warning

Calling !! on a nullable type will throw a NullPointerException at runtime in case the value is null. It should be avoided.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants