Enforce bytecode-only class and instance init bodies

This commit is contained in:
Sergey Chernov 2026-02-13 01:37:16 +03:00
parent 70ba424ef9
commit 05cba5b653
2 changed files with 31 additions and 3 deletions

View File

@ -37,7 +37,8 @@ class ClassStaticFieldInitStatement(
override val pos: Pos = startPos
override suspend fun execute(scope: Scope): Obj {
val initValue = initializer?.execute(scope)?.byValueCopy() ?: ObjNull
val initValue = initializer?.let { execBytecodeOnly(scope, it, "class static field init") }?.byValueCopy()
?: ObjNull
val cls = scope.thisObj as? ObjClass
?: scope.raiseIllegalState("static field init requires class scope")
return if (isDelegated) {
@ -98,4 +99,13 @@ class ClassStaticFieldInitStatement(
initValue
}
}
private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj {
val bytecode = when (stmt) {
is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt
is BytecodeBodyProvider -> stmt.bytecodeBody()
else -> null
} ?: scope.raiseIllegalState("$label requires bytecode statement")
return bytecode.execute(scope)
}
}

View File

@ -38,7 +38,7 @@ class InstanceFieldInitStatement(
override val pos: Pos,
) : Statement() {
override suspend fun execute(scope: Scope): Obj {
val initValue = initializer?.execute(scope)?.byValueCopy()
val initValue = initializer?.let { execBytecodeOnly(scope, it, "instance field init") }?.byValueCopy()
?: if (isLateInitVal) ObjUnset else ObjNull
scope.addItem(
storageName,
@ -54,6 +54,15 @@ class InstanceFieldInitStatement(
)
return ObjVoid
}
private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj {
val bytecode = when (stmt) {
is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt
is BytecodeBodyProvider -> stmt.bytecodeBody()
else -> null
} ?: scope.raiseIllegalState("$label requires bytecode statement")
return bytecode.execute(scope)
}
}
class InstancePropertyInitStatement(
@ -100,7 +109,7 @@ class InstanceDelegatedInitStatement(
override val pos: Pos,
) : Statement() {
override suspend fun execute(scope: Scope): Obj {
val initValue = initializer.execute(scope)
val initValue = execBytecodeOnly(scope, initializer, "instance delegated init")
val accessType = ObjString(accessTypeLabel)
val finalDelegate = try {
initValue.invokeInstanceMethod(
@ -127,4 +136,13 @@ class InstanceDelegatedInitStatement(
}
return ObjVoid
}
private suspend fun execBytecodeOnly(scope: Scope, stmt: Statement, label: String): Obj {
val bytecode = when (stmt) {
is net.sergeych.lyng.bytecode.BytecodeStatement -> stmt
is BytecodeBodyProvider -> stmt.bytecodeBody()
else -> null
} ?: scope.raiseIllegalState("$label requires bytecode statement")
return bytecode.execute(scope)
}
}