Enforce bytecode-only class and instance init bodies
This commit is contained in:
parent
70ba424ef9
commit
05cba5b653
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user