clearer error for VM limitation cannot load label address as value

This commit is contained in:
Irmen de Jong 2022-11-12 13:45:02 +01:00
parent 9d7b9771c2
commit e6688f4b9d
3 changed files with 39 additions and 5 deletions

View File

@ -242,4 +242,32 @@ main {
}
exc.message shouldContain("does not support non-IR asmsubs")
}
test("addresses from labels/subroutines not yet supported in VM") {
val src = """
main {
sub start() {
mylabel:
ubyte variable
uword @shared pointer1 = &main.start
uword @shared pointer2 = &start
uword @shared pointer3 = &main.start.mylabel
uword @shared pointer4 = &mylabel
uword[] @shared ptrs = [&variable, &start, &main.start, &mylabel, &main.start.mylabel]
}
}
"""
val othertarget = Cx16Target()
compileText(othertarget, true, src, writeAssembly = true, keepIR=true) shouldNotBe null
val target = VMTarget()
val result = compileText(target, false, src, writeAssembly = true)!!
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
val exc = shouldThrow<Exception> {
VmRunner().runProgram(virtfile.readText())
}
exc.message shouldContain("cannot yet load a label address as a value")
}
})

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix IR/VM compiler crash: subroutine address in array: uword[] @shared ptrs = [&x1, &x2, &start] + unit test
- IRFileReader should parse the p8ir file with xml parser
- 6502 codegen: make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``p8v_``? Or not worth it (most 3 letter opcodes as variables are nonsensical anyway)
then we can get rid of the instruction lists in the machinedefinitions as well. This is already no problem at all in the IR codegen.
@ -29,6 +28,7 @@ Compiler:
- ir: peephole opt: renumber registers in chunks to start with 1 again every time (but keep entry values in mind!)
- ir peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out!)
- ir: add more optimizations in IRPeepholeOptimizer
- vm: somehow be able to load a label address as value? (VmProgramLoader)
- see if we can let for loops skip the loop if end<start, like other programming languages. Without adding a lot of code size/duplicating the loop condition.
this is documented behavior to now loop around but it's too easy to forget about!
Lot of work because of so many special cases in ForLoopsAsmgen.....

View File

@ -48,7 +48,7 @@ class VmProgramLoader {
val replacement = addAssemblyToProgram(chunk, programChunks, variableAddresses)
chunkReplacements += replacement
}
is IRInlineBinaryChunk -> TODO("inline binary data not yet supported in the VM")
is IRInlineBinaryChunk -> throw IRParseException("inline binary data not yet supported in the VM") // TODO
is IRCodeChunk -> programChunks += chunk
else -> throw AssemblyError("weird chunk type")
}
@ -153,11 +153,15 @@ class VmProgramLoader {
} else {
// placeholder is not a variable, so it must be a label of a code chunk instead
val target: IRCodeChunk? = chunks.firstOrNull { it.label==label }
val opcode = chunk.instructions[line].opcode
if(target==null)
throw IRParseException("placeholder not found in variables nor labels: $label")
else {
require(chunk.instructions[line].opcode in OpcodesThatBranch)
else if(opcode in OpcodesThatBranch) {
chunk.instructions[line] = chunk.instructions[line].copy(branchTarget = target, value = null)
} else if(opcode in OpcodesWithMemoryAddressAsValue) {
throw IRParseException("vm cannot yet load a label address as a value: ${chunk.instructions[line]}") // TODO
} else {
throw IRParseException("vm cannot yet load a label address as a value: ${chunk.instructions[line]}") // TODO
}
}
} else {
@ -244,7 +248,9 @@ class VmProgramLoader {
DataType.ARRAY_UW -> {
for(elt in it) {
if(elt.addressOf!=null) {
val symbolAddress = symbolAddresses.getValue(elt.addressOf!!.joinToString("."))
val name = elt.addressOf!!.joinToString(".")
val symbolAddress = symbolAddresses[name]
?: throw IRParseException("vm cannot yet load a label address as a value: ${name}") // TODO
memory.setUW(addr, symbolAddress.toUShort())
} else {
memory.setUW(addr, elt.number!!.toInt().toUShort())