TEST FOR B::Assembler.pm AND B::Disassembler.pm
Description
The general idea is to test by assembling a choice set of assembler instructions, then disassemble them, and check that we've completed the round trip. Also, error checking of Assembler.pm is tested by feeding it assorted errors.
Since Assembler.pm likes to assemble a file, we comply by writing a text file. This file contains three sections:
testing operand categories
use each opcode
erronous assembler instructions
An "operand category" is identified by the suffix of the PUT_/GET_ subroutines as shown in the %Asmdata::insn_data
initialization, e.g. opcode ldsv
has operand category svindex
:
insn_data{ldsv} = [1, \&PUT_svindex, "GET_svindex"];
Because Disassembler.pm also assumes input from a file, we write the resulting object code to a file. And disassembled output is written to yet another text file which is then compared to the original input. (Erronous assembler instructions still generate code, but this is not written to the object file; therefore disassembly bails out at the first instruction in error.)
All files are kept in memory by using TIEHASH.
Caveats
An error where Assembler.pm and Disassembler.pm agree but Assembler.pm generates invalid object code will not be detected.
Due to the way this test has been set up, failure of a single test could cause all subsequent tests to fail as well: After an unexpected assembler error no output is written, and disassembled lines will be out of sync for all lines thereafter.
Not all possibilities for writing a valid operand value can be tested because disassembly results in a uniform representation.
Maintenance
New opcodes are added automatically.
A new operand category will cause this program to die ("no operand list for XXX"). The cure is to add suitable entries to %goodlist
and %badlist
. (Since the data in Asmdata.pm is autogenerated, it may also happen that the corresponding assembly or disassembly subroutine is missing.) Note that an empty array as a %goodlist
entry means that opcodes of the operand category do not take an operand (and therefore the corresponding entry in %badlist
should have one). An undef
entry in %badlist
means that any value is acceptable (and thus there is no way to cause an error).
Set $dbg
to debug this test.