From Didier Gautheron: Bug #2040: Fix up goto at compilation time in gencode.c

svn path=/trunk/; revision=23658
This commit is contained in:
Bill Meier 2007-11-28 22:37:33 +00:00
parent e2598d0c92
commit 6d4dda3327
1 changed files with 41 additions and 0 deletions

View File

@ -439,11 +439,52 @@ gencode(dfwork_t *dfw, stnode_t *st_node)
void
dfw_gencode(dfwork_t *dfw)
{
int id, id1, length;
dfvm_insn_t *insn, *insn1, *prev;
dfvm_value_t *arg1;
dfw->insns = g_ptr_array_new();
dfw->loaded_fields = g_hash_table_new(g_direct_hash, g_direct_equal);
dfw->interesting_fields = g_hash_table_new(g_direct_hash, g_direct_equal);
gencode(dfw, dfw->st_root);
dfw_append_insn(dfw, dfvm_insn_new(RETURN));
/* fixup goto */
length = dfw->insns->len;
for (id = 0, prev = NULL; id < length; prev = insn, id++) {
insn = g_ptr_array_index(dfw->insns, id);
arg1 = insn->arg1;
if (insn->op == IF_TRUE_GOTO || insn->op == IF_FALSE_GOTO) {
dfvm_opcode_t revert = (insn->op == IF_FALSE_GOTO)?IF_TRUE_GOTO:IF_FALSE_GOTO;
id1 = arg1->value.numeric;
do {
insn1 = g_ptr_array_index(dfw->insns, id1);
if (insn1->op == revert) {
/* this one is always false and the branch is not taken*/
id1 = id1 +1;
continue;
}
else if (insn1->op == READ_TREE && prev && prev->op == READ_TREE &&
prev->arg2->value.numeric == insn1->arg2->value.numeric) {
/* hack if it's the same register it's the same field
* and it returns the same value
*/
id1 = id1 +1;
continue;
}
else if (insn1->op != insn->op) {
/* bail out */
arg1 = insn->arg1;
arg1->value.numeric = id1;
break;
}
arg1 = insn1->arg1;
id1 = arg1->value.numeric;
} while (1);
}
}
}