It's possible to call a method designed for a me object with any
nonsense in the first argument. By design, this should look up the
clean function handler in the script context instead of the one in the
offspring object. However the "me" handle needs to be nulled out,
or else accessing properties will leak through from the previous
object.
Fixes saving games in DEVO Presents: Adventures of the Smart Patrol.
At first glance it would seem we could use funcSym.nargs for this,
except it is fixed to the number of args in the function definition.
We also can't derive it from the argument list that is sent through,
as it is truncated/padded with VOIDs. To keep things simple, track
paramCount as part of CFrame.
Previously, the Lingo state would be frozen by persisting the frames on
the bottom of the callstack with a special flag. This required extra
logic to determine whether or not the callstack was intended to be empty
after execution finished, with some complex edge cases.
The new approach is to swap out the LingoState object on the window,
meaning that an empty callstack always signifies execution has completed.
It remains to be seen if we'll need to track more than one frozen
context; for now it seems to be okay.
Fixes driving to locations in DEVO Presents: Adventures of the Smart Patrol.
The previous arrangement was to copy the bits of Lingo state back and forth from
the Window object to the Lingo instance, and query the window for the
callstack. This refactor consolidates the current Lingo state into a single
struct, owned by the Window object and accessible via a pointer on the
Lingo object.
The datum constructor is overloaded and handles setting the type.
Instead of setting the type by hand we leverage the constructor.
The in this commit are mainly for Datums of type int.
Various equality checks used the first datum to signal the value of the
check. Setting the Datums type to int in the process.
Datum's destructor only removes the item that corresponds with it's
current type.
For example, when comparing two strings, d1 and d2. D1's type would
be set to int indicating if there was a match. D1, now being an int,
would not remove the string on destruction. The result is a memory leak.
Given an item list: "lorem,ipsum,dolor,sit,amet" and the lingo code:
`delete item 1 of list`.
The first item "lorem" was deleted but without the comma. Leaving an
empty first item.
In Star Trek: The Next Generation Interactive Technical Manual the
code repeatedly deleted the first item till it encountered an `@`.
The result was a loop in which it was stuck.
- Includes lingo test.
This fixes https://trello.com/c/bucHPI2F/429-majestic-regression
hasFrozenContext is now a function which checks the call stack for
frozen contexts. Not updating this variable manually leaves less room
for error.
Since there may be frames left on the call stack after Lingo::execute()
is called now, it isn't safe to share one call stack between several
movies executing in parallel.