Q: When I build my project that has very deeply nested statements, NTK runs out of memory and quits. What's going wrong?
A: The deep nesting in your project is causing the compiler to overflow the stack space available in NTK. NTK 1.6 is more likely than than NTK 1.5 to suffer this problem due to new compiler code which nests deeper while parsing if-then-else statements, causing the stack to overflow into the application heap.
If you see an inadvertent crash in NTK during a save operation or a package build:
1) If you are familiar with MacsBug, examine the stack. This particular case will show up in the stack as several calls to the same function before the actual crash.
2) Otherwise, temporarily reduce the number of "else" branches and rebuild the package. If the problem disappears, stack overflow is the prime suspect.
There are at least three ways to avoid this problem and possibly improve performance at the same time:
1) Re-arrange the 'else' statements to resemble a balanced tree
2) Instead of If-then-else statements use:
An array of functions (with integers as selectors)
A frame of functions (with symbols as selectors)
3) Finally, as a temporary work around, you can increase the stack size using the ResEdit application.
Re-arrange the 'else' statements to resemble a balanced tree
This solution is the simplest to implement if you need to change existing code. It accommodates non-contiguous integer selectors, and in most cases is faster.
For example, the following code:
if x = 1 then dosomething else if x = 2 then doSomethingElse else if x = 3 then doYetAnotherThing else if x = 4 then doOneMoreThing else if x = 5 then doSomethingSimple else if x = 6 then doThatThing else if x = 7 then doThisThing else // x = 8 doTheOtherThing
...can be rewritten like this:
if x <= 4 then if x <= 2 then if x = 1 then doSomething else // x = 2 doSomethingElse else if x = 3 then doYetAnotherThing else // x = 4 doOneMoreThing else if x <= 6 then if x = 5 then doSomethingSimple else // x = 6 doThatThing else if x = 7 then doThisThing else // x = 8 doTheOtherThing;
Note that the if/then/else statement nesting is "unusual" to illustrate the nesting that the compiler must make each statement is nested as the compiler would process it.
Use an array of functions with integer selectors
Replace a long if-then-else statement with an array of functions. The code is more compact and readable. For a large set of alternatives, the faster direct lookup should compensate for the extra function call. This approach is most useful for a contiguous range of selector values (e.g., 11 to 65). It can accommodate a few "holes" (for example, 11 to 32, 34 to 56, 58 to 65). It is not practical for non-contiguous selectors (e.g., 31, 77, 256, 1038...)
For example, the following code:
if x = 1 then dosuchandsuch; else if x = 2 then dosomethingelse; else if x = 3 then andsoon;
...can be rewritten like this:
cmdArray := [func() dosuchandsuch, func() dosomethingelse, func() andsoon]; call cmdArray[x] with ();
Use a frame of functions with symbols for selectors
This alternative provides the flexibility of using symbols for selecting the outcome.
For example, the following code:
if x = 'foo then dosuchandsuch; else if x = 'bar then dosomethingelse; else if x = 'baz then andsoon;
...can be rewritten like this:
cmdFrame := {foo: func() dosuchandsuch, bar: func() dosomethingelse, baz: func() andsoon}; call cmdFrame.(x) with ();
Increase NTK's stack size using the ResEdit application
Open the Newton Toolkit application with ResEdit.
Double-click on the "mem!
" resource icon
Double-click on resource ID 1000
named "Additional NTK Memory Requirements"
Change the fifth (and last) value. This is an hexadecimal number. In NTK 1.6, you should see "0001 8000
" which is 98304
bytes (or 96k
) to add to the total stack size. For example, to increase this value to 128k
= 131072
bytes change the hexadecimal value to "0002 0000
".