SCM function storage fixes.#537
Conversation
a580150 to
b4377c1
Compare
b4377c1 to
7447d73
Compare
|
Can it be (unit) tested? |
|
All unit tests already heavy depend on SCM functions. Nothing broken. Still no idea if this fixes the error with looping SCM function call stack, but for sure it patches at least one hole. |
|
Hard to tell without code. Looking at the changes, I'm thinking we can use R*'s CPool to maintain pool of functions, all methods are conveniently here already (via psdk). You just need to create new CPool with 0x400 elements |
|
I doubt the container management itself is the problem. If anything maybe it would be better to just have array of elements instead of array of pointers for performance reasons. Maybe it has something to do with the cleanup and after cleanup use? Seems to occur more frequently after starting new session. |
|
Try some older CLEO version? Maybe recent regression |
|
Thing is I did not used script log before. Activated it after doing some memory handling errors in script. |
Use std::array
|
I don't have enough context for this refactoring. Are we solving some actual issues here? Can they be expressed in unit tests? |
I would basically repeat the description of the PR. ScmFunction manager was allowing 0 as function identifier while 0 is default value for scripts with empty callstack. Class was also returning nullptr when junk id/index was used in Get method. |
|
So why not just change default id to 1? |
What do you mean? It is common memory is usually initialized as 0. For sure all foreign scripts will have that value set to 0. Encapsulating some properties of the storage also makes sense, as it forces to use proper methods. |
|
Show me the exact issue that this change fixes. Write a test. |
If I understand correctly you need to change all |
|
There need to be no other scripts using SCM functions. "After foo" is printed, meaning script B is executing code from script A, plus destroying its call stack. |
But after a full circle allocation place will be warped to 0. |
No, which is why I mentioned 'all'. After warping, you skip 0 again
|
|
Slot 0 will be used for the "empty call stack" function, then you don't need to check for 0 also simplifies +1/-1 in other places where it is easy to make mistakes |
|
|
what error does it produce with this change? |
|
So how to get SHOW_ERROR("CLEO function with id %d not found in the storage!", id); ? |
how's that possible? We don't provide public access to it to my knowledge |
Have script with SCMFunction field corrupted or uninitialized. The fact I have no idea how to reproduce it right now from script in other way than using memory write does not mean it can not happen in the wild. |
Encapsulation exists for a reason. To prevent us from ourself. Now it is obvious it is impossible to do something unexpected. |
Tricky to unit test as the error is shown only when non existent function id is requested. Due to global nature of the storage it is not predictable. |
| if (++allocationPlace >= Store_Size) allocationPlace = 0; // end of store reached | ||
| if (allocationPlace == start_search) | ||
| lastAllocIdx++; | ||
| if (lastAllocIdx >= Store_Size) lastAllocIdx = 0; // warp around |
There was a problem hiding this comment.
Are we creating a functon at slot 0 after warping?
There was a problem hiding this comment.
Yes. Slot like any other.
There was a problem hiding this comment.
Pushed update. Not sure if that is an improvement. +1 just migrated into other places and slot 0 is now unused. Which is weird thing to do.
There was a problem hiding this comment.
but isn't that what you ultimately tried to do? if the script calls return with uninitialized ScmFunctionId it should not get access to valid function
There was a problem hiding this comment.
In other words, 0 is never a valid slot for the function
There was a problem hiding this comment.
0 is not valid function ID. Index is internal businesses of storage class.
6322bbb to
40b941f
Compare
|
|
I should've posted here, instead of #550. This MR does not solve the fundamental problem in the SCM functions architecture, which is that all scripts use the linear shared array for functions and access to them is given based on an unrestricted mutable field. Any script can modify its function id (intentionally or not) and there is no way to validate legitimacy of that access, as demonstrated in #550 (comment). This PR only shifts already existing validation from return command to storage getter, providing different error message, when the function does not exist. In my opinion, renaming index to id, adding private class properties, etc, is just a ceremony that does not fix the actual fundamental issue described above. So far, we identified and fixed one specific edge case, which could bite the scripter even on legitimate code, which is the stale function index in terminated scripts. #548 + #550 combined solve THIS particular edge case. The other issue remains present. Which is why I'm against doing changes that bring no real value. |


Introduced distinction between function id and index in storage.
Default value 0 of CRunningScript::ScmFunction no longer can identify valid function.
Some internal properties of ScmFunction are now private.
Used std::array instead of c-arrays.
Removed some magic numbers.
Showing errors on errors instead of pretending everything is fine.