mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
clearer error for VM limitation cannot load label address as value
This commit is contained in:
parent
9d7b9771c2
commit
e6688f4b9d
@ -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")
|
||||
}
|
||||
})
|
@ -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.....
|
||||
|
@ -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())
|
||||
|
Loading…
Reference in New Issue
Block a user