core: Support dependent strings for concatenation
This makes affects all code that uses AvmString::concat, but the most important case is "a" + "b" in both AVM1 and AVM2.
(also added it to AS3 String::concat while I was there)
With the PR, the code like
var a = "";
for (var i = 0; i < N; i += 1) { a += "x" };
Will allocate a new string buffer log(N) times, instead of N times. (note that it'll still allocate N string objects) This makes most code like this super fast instead of... crashing the player.
Should fix several SWFs, including https://github.com/ruffle-rs/ruffle/issues/9736 - though I didn't test it yet.
I still want to test the code a bit more (tbh adding test-only code to inspect string internals would be great 😢) and mostly get a safety review from @moulins if possible.
Also might still refactor it a bit, this entire code might be moved to AvmStringRepr to keep AvmString unsafe-free and avoid exposing internal pointers.
Forgot to add: for code that is not egregiously written (so most code), this might slightly increase our memory usage.
Since if every string concat is only ever done once, like data["c"+i]=1, then the overallocation is never useful.
That said, strings are usually not a huge % of total memory used, so it shouldn't make a noticeable difference on average.
https://github.com/ruffle-rs/ruffle/issues/9736 is fixed with this PR 🥳
(After rebasing, I have amended this commit with a cargo fmt and a tiny clippy lint fix, just to get rid of the red CI crosses, I hope you don't mind...)
Note: the PR is still missing size overflow checks, but the pointer logic should be stable now.