OpenBoot 3.x Command Reference Manual

Using patch and (patch)

OpenBoot provides the ability to change the definition of a previously compiled Forth word using high-level Forth language. While the changes will typically be made in the appropriate source code, the patch facility provides a means of quickly correcting errors uncovered during debugging.

patch reads the input stream for the following information:

For example, consider the following example in which the word test is replaced with the number 555:


ok : patch-me  test 0 do  i . cr  loop ;
ok patch 555 test patch-me
ok see patch-me
: patch-me
	h# 555 0 do
		i . cr
	loop
;

When using patch, some care must be taken to select the right word to replace. This is especially true if the word you are replacing is used several times within the target word and the occurrence of the word that you want to replace is not the first occurrence within the target word. In such a case, some subterfuge is required.


ok : patch-me2  dup dup dup ( This third dup should be drop) ;
ok : xx dup ;
ok patch xx dup patch-me2
ok patch xx dup patch-me2
ok patch drop dup patch-me2
ok see patch-me2
: patch-me2
	xx xx drop
;

Another use for patch is the case where the word to be patched contains some functionality that needs to be completely discarded. In this case, the word exit should be patched over the first word whose functionality is to be eliminated. For example, consider a word whose definition is:


ok : foo good bad unneeded ;

In this example, the functionality of bad is incorrect and the functionality of unneeded should be discarded. A first attempt to patch foo might be:


ok : right this that exit ;
ok patch right bad foo 

on the expectation that the use of exit in the word right would prevent the execution of unneeded. Unfortunately, exit terminates the execution of the word which contains it, in this case right. The correct way to patch foo is:


ok : right this that ;
ok patch right bad foo 
ok patch exit unneeded foo 

(patch) is similar to patch except that (patch) obtains its arguments from the stack. The stack diagram for (patch) is:

( new-n1 num1? old-n2 num2? xt -- )

where:

For example, consider the following example in which we reverse the affect of our first patch example by replacing the number 555 with test:


ok see patch-me
: patch-me
	h# 555 0 do
		i . cr
	loop
;
ok ['] test false 555 true ['] patch-me (patch)
ok see patch-me
: patch-me
	test 0 do
		i . cr
	loop
;