Obscure circumstances cause the erroneous message: This is in response to apparently valid code that compiles
correctly under 6.21. The error is not erroneous, but the location given is. If an error
occurs when compiling the infix symbol table, the last veneer routine
is quoted. This can be fixed like this: Inform 6.21 didn't have the 'branch out of range' error, but Infix
instructions like '; story' when there were very many arrays or routines could cause illegal
opcode or other problems.
One possibility is to break Symb__Tab into three separate routines, so
that it can't possibly overflow. However, a general solution is to
extend the maximum range of branches, and the maximum size of the
symbol table, fourfold like this:
About Patches
Issue C63003 [previous patch]
Erroneous "Branch out of range" message
Submitted by: Graham Nelson
Appeared in: Compiler 6.30
Fixed in: -
Problem
File "<veneer routine 'RT__ChPrintS'>"; Line 1 # Fatal error:
Branch out of range: divide the routine up?
Solution (by Cedric Knight)
diff -u inform630ref\veneer.c .\veneer.c
--- inform630ref\veneer.c Fri Feb 27 06:30:00 2004
+++ .\veneer.c Sat Mar 20 21:38:44 2004
@@ -2163,6 +2163,8 @@
assign_symbol(j,
assemble_routine_header(2, FALSE, "Symb__Tab", &null_dbgl, FALSE, j),
ROUTINE_T);
+ restart_lexer("", "Symb__Tab");
+
sflags[j] |= SYSTEM_SFLAG + USED_SFLAG;
if (trace_fns_setting==3) sflags[j] |= STAR_SFLAG;
diff -u inform630ref\asm.c .\asm.c
--- inform630ref\asm.c Fri Feb 27 06:30:00 2004
+++ .\asm.c Sat Mar 20 21:49:12 2004
@@ -1531,13 +1530,18 @@
{ if (asm_trace_level >= 4)
printf("Branch detected at offset %04x\n", pc);
j = (256*zcode_holding_area[i] + zcode_holding_area[i+1]) & 0x7fff;
+ addr = label_offsets[j]-pc;
if (asm_trace_level >= 4)
printf("To label %d, which is %d from here\n",
- j, label_offsets[j]-pc);
- if ((label_offsets[j] >= pc+2) && (label_offsets[j] < pc+64))
+ j, addr);
+ if ((addr > 2) && (addr < 64))
{ if (asm_trace_level >= 4) printf("Short form\n");
zcode_markers[i+1] = DELETED_MV;
}
+ else if (addr<-0x2000 || addr>0x1fff)
+ { if (asm_trace_level >= 4) printf("Inverted branch and jump\n");
+ zcode_markers[i+1] = EXPANDED_MV;
+ }
}
}
@@ -1567,6 +1571,7 @@
label = label_next[label];
}
if (zcode_markers[i] != DELETED_MV) new_pc++;
+ if (zcode_markers[i] == EXPANDED_MV) new_pc+=2;
}
}
@@ -1578,19 +1583,28 @@
{ switch(zcode_markers[i])
{ case BRANCH_MV:
long_form = 1; if (zcode_markers[i+1] == DELETED_MV) long_form = 0;
+ if (zcode_markers[i+1] == EXPANDED_MV) long_form = 3;
j = (256*zcode_holding_area[i] + zcode_holding_area[i+1]) & 0x7fff;
branch_on_true = ((zcode_holding_area[i]) & 0x80);
offset_of_next = new_pc + long_form + 1;
addr = label_offsets[j] - offset_of_next + 2;
- if (addr<-0x2000 || addr>0x1fff)
+ if (addr<-0x8000 || addr>0x7fff)
fatalerror("Branch out of range: divide the routine up?");
if (addr<0) addr+=(int32) 0x10000L;
- addr=addr&0x3fff;
- if (long_form==1)
- { zcode_holding_area[i] = branch_on_true + addr/256;
+ if (long_form==3)
+ { zcode_holding_area[i] = (0x80 ^ branch_on_true) + 0x40 + 5;
+ transfer_byte(zcode_holding_area + i); new_pc++;
+ zcode_holding_area[i] = 0x8c;
+ transfer_byte(zcode_holding_area + i); new_pc++;
+ zcode_holding_area[i] = addr/256;
+ zcode_holding_area[i+1] = addr%256;
+ }
+ else if (long_form==1)
+ { addr=addr&0x3fff;
+ zcode_holding_area[i] = branch_on_true + addr/256;
zcode_holding_area[i+1] = addr%256;
}
else
@@ -1619,7 +1633,8 @@
default:
switch(zcode_markers[i] & 0x7f)
- { case NULL_MV: break;
+ { case EXPANDED_MV:
+ case NULL_MV: break;
case VARIABLE_MV:
case OBJECT_MV:
case ACTION_MV:
diff -u inform630ref\header.h .\header.h
--- inform630ref\header.h Fri Feb 27 06:30:00 2004
+++ .\header.h Sat Mar 20 18:24:28 2004
@@ -1836,8 +1836,9 @@
#define LABEL_MV 36 /* Ditto: marks "jump" operands */
#define DELETED_MV 37 /* Ditto: marks bytes deleted from code */
-#define BRANCH_MV 38 /* Used in "asm.c" for routine coding */
-#define BRANCHMAX_MV 58 /* In fact, the range BRANCH_MV to
+#define EXPANDED_MV 38 /* asm.c again: marks branch to invert */
+#define BRANCH_MV 39 /* Used in "asm.c" for routine coding */
+#define BRANCHMAX_MV 59 /* In fact, the range BRANCH_MV to
BRANCHMAX_MV all means the same thing.
The position within the range means
how far back from the label to go
Last updated 17 April 2013.
This site is no longer supported; information may be out of date.
Maintained as a historical archive by the Interactive Fiction Technology Foundation.
Copyright 1993-2018 IFTF, CC-BY-SA unless otherwise noted.
This page was originally managed by Roger Firth.