mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +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")
|
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
|
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
|
- 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)
|
- 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.
|
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: 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 peephole opt: reuse registers in chunks (but keep result registers in mind that pass values out!)
|
||||||
- ir: add more optimizations in IRPeepholeOptimizer
|
- 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.
|
- 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!
|
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.....
|
Lot of work because of so many special cases in ForLoopsAsmgen.....
|
||||||
|
@ -48,7 +48,7 @@ class VmProgramLoader {
|
|||||||
val replacement = addAssemblyToProgram(chunk, programChunks, variableAddresses)
|
val replacement = addAssemblyToProgram(chunk, programChunks, variableAddresses)
|
||||||
chunkReplacements += replacement
|
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
|
is IRCodeChunk -> programChunks += chunk
|
||||||
else -> throw AssemblyError("weird chunk type")
|
else -> throw AssemblyError("weird chunk type")
|
||||||
}
|
}
|
||||||
@ -153,11 +153,15 @@ class VmProgramLoader {
|
|||||||
} else {
|
} else {
|
||||||
// placeholder is not a variable, so it must be a label of a code chunk instead
|
// 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 target: IRCodeChunk? = chunks.firstOrNull { it.label==label }
|
||||||
|
val opcode = chunk.instructions[line].opcode
|
||||||
if(target==null)
|
if(target==null)
|
||||||
throw IRParseException("placeholder not found in variables nor labels: $label")
|
throw IRParseException("placeholder not found in variables nor labels: $label")
|
||||||
else {
|
else if(opcode in OpcodesThatBranch) {
|
||||||
require(chunk.instructions[line].opcode in OpcodesThatBranch)
|
|
||||||
chunk.instructions[line] = chunk.instructions[line].copy(branchTarget = target, value = null)
|
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 {
|
} else {
|
||||||
@ -244,7 +248,9 @@ class VmProgramLoader {
|
|||||||
DataType.ARRAY_UW -> {
|
DataType.ARRAY_UW -> {
|
||||||
for(elt in it) {
|
for(elt in it) {
|
||||||
if(elt.addressOf!=null) {
|
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())
|
memory.setUW(addr, symbolAddress.toUShort())
|
||||||
} else {
|
} else {
|
||||||
memory.setUW(addr, elt.number!!.toInt().toUShort())
|
memory.setUW(addr, elt.number!!.toInt().toUShort())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user