newLISP Development Release v.10.5.5

Started by Lutz, November 20, 2013, 06:39:05 AM

Previous topic - Next topic

hartrock

#15
[update2] gcc is not guilty; see reply below. Wrong code example has led me to the problem...

[update] Wrong code example removed.



Note:

It seems to be difficult to create an example with minimal code to trigger this bug (have tried a while); so I don't know how to bug report this to the gcc maintainers (any idea?).



[update2] No wonder this is difficult, if there is no bug...

johu

#16
Hello, Lutz.



I finished the translartion of v.10.5.5's manual.



https://skydrive.live.com/?cid=23a9a25e1aec3626&sc=documents&id=23A9A25E1AEC3626!1450">newlisp_manual-10505



And in 10.5.5's manual,



line 2796
Quoteto the name-space which owns the that symbol.</p>

line 9160
Quote   but probabilities are compounded using the Chi&sup2; method.

Are these OK?



Regards,

Lutz

#17
Thanks Johu, there are more changes coming in the 10.5.6 manual.



http://www.newlisp.org/downloads/development/inprogress/">http://www.newlisp.org/downloads/develo ... nprogress/">http://www.newlisp.org/downloads/development/inprogress/

hartrock

Quote from: "Lutz"Looking at the pointer values passed and assigned and the resultStackIdx, I see that the sequence of assignments is correct. First: args = arrayList(args, FALSE) second: *(++resultStackIdx) = args



But incrementing resultStackIdx only works the first time, the second time entering the apply statement, resultStackIdx doesn't increment and is stuck at its old value forever, no matter how often I enter the apply statement. Now the old pointer is overwritten again and again and has never a chance to get processed by popResult() higher up in evaluateExpression() for freeing cells and memory.



So it seems not to be a sequence point problem, but a problem with the ++ operator in gcc but only under certain circumstances.

It's not a gcc problem.

The macro:
newlisp.h:#define pushResult(A) (*(++resultStackIdx) = (UINT)(A))

, called as:
pushResult(args = arrayList(args, FALSE));
, which will be expanded to:
(*(++resultStackIdx) = (unsigned long)(args = arrayList(args, 0)));
, has side effects! As far as I know the compiler need not assume this possibility, so it can freely ++resultStackIdx before calling arrayList().

Problem is, that resultStackIdx will be changed by both ++resultStackIdx and calling arrayList(). Call chain is arrayList() -> copyCell() -> popResult() (last one changes resultStackIdx).

So it depends on the sequence of changing resultStackIdx what happens: moving arrayList() call into an extra statement before ++resultStackIdx, enforces the correct one (like already done).



As a rule it could be stated: safest is to pushResult() only a pointer already computed (it's not visible which call could have side effects to global resultStackIdx, and there may be a change in called function later). A single developer may break this rule, if he knows, that there are and will be no side effects from a call ;-)