avm2: Fix handling of public indices with nested iteration

This more closely aligns our code with the corresponding avmplus code.
A user-supplied index of '0' is special-cased, and we correctly
resume iteration when a public index mismatch is detected.
This commit is contained in:
Aaron Hill 2023-11-25 12:18:12 -05:00 committed by Nathan Adams
parent a2021cd3e2
commit f12f457f5d
6 changed files with 76 additions and 2 deletions

View File

@ -91,15 +91,28 @@ impl<K: Eq + PartialEq + Hash, V> DynamicMap<K, V> {
}
pub fn next(&self, index: usize) -> Option<usize> {
// Start iteration from the beginning
if index == 0 {
if let Some(real) = self.public_to_real_index(1) {
self.real_index.set(real);
self.public_index.set(1);
return Some(1);
} else {
self.public_index.set(0);
self.real_index.set(0);
return None;
}
}
// If the public index is zero than this is the first time this is being enumerated,
// if index != self.public_index, then we are enumerating twice OR we mutated while enumerating.
//
// Regardless of the reason, we just need to sync the supplied index to the real index.
if self.public_index.get() == 0 || index != self.public_index.get() {
if let Some(real) = self.public_to_real_index(index) {
// Pick up where we left off in the iteration
// See https://github.com/adobe/avmplus/blob/858d034a3bd3a54d9b70909386435cf4aec81d21/core/avmplusHashtable.cpp#L395
self.real_index.set(real);
self.public_index.set(index + 1);
return Some(self.public_index.get());
self.public_index.set(index);
} else {
self.public_index.set(0);
self.real_index.set(0);

View File

@ -0,0 +1,49 @@
package {
import flash.display.MovieClip;
public class Test extends MovieClip {
public function Test() {
// constructor code
}
}
}
import flash.utils.Dictionary;
function testNestedIter(obj: Object) {
for (var i = 0; i < 100; i++) {
obj["Key " + i] = i
};
var seen_main = [];
var seen_sub = [];
for (var key in obj) {
seen_main.push("Key: '" + key + "' Value: " + obj[key]);
if (seen_main.length == 50) {
for (var key in obj) {
seen_sub.push("Key: '" + key + "' Value: " + obj[key]);
}
}
}
seen_main.sort();
seen_sub.sort();
trace("Seen main: " + seen_main.length);
trace("Seen sub: " + seen_sub.length);
trace(seen_main);
trace(seen_sub);
}
trace("Testing Object nested iteration");
testNestedIter(new Object());
trace()
trace("Testing Dictionary nested iteration");
testNestedIter(new Dictionary());

View File

@ -0,0 +1,11 @@
Testing Object nested iteration
Seen main: 100
Seen sub: 100
Key: 'Key 0' Value: 0,Key: 'Key 1' Value: 1,Key: 'Key 10' Value: 10,Key: 'Key 11' Value: 11,Key: 'Key 12' Value: 12,Key: 'Key 13' Value: 13,Key: 'Key 14' Value: 14,Key: 'Key 15' Value: 15,Key: 'Key 16' Value: 16,Key: 'Key 17' Value: 17,Key: 'Key 18' Value: 18,Key: 'Key 19' Value: 19,Key: 'Key 2' Value: 2,Key: 'Key 20' Value: 20,Key: 'Key 21' Value: 21,Key: 'Key 22' Value: 22,Key: 'Key 23' Value: 23,Key: 'Key 24' Value: 24,Key: 'Key 25' Value: 25,Key: 'Key 26' Value: 26,Key: 'Key 27' Value: 27,Key: 'Key 28' Value: 28,Key: 'Key 29' Value: 29,Key: 'Key 3' Value: 3,Key: 'Key 30' Value: 30,Key: 'Key 31' Value: 31,Key: 'Key 32' Value: 32,Key: 'Key 33' Value: 33,Key: 'Key 34' Value: 34,Key: 'Key 35' Value: 35,Key: 'Key 36' Value: 36,Key: 'Key 37' Value: 37,Key: 'Key 38' Value: 38,Key: 'Key 39' Value: 39,Key: 'Key 4' Value: 4,Key: 'Key 40' Value: 40,Key: 'Key 41' Value: 41,Key: 'Key 42' Value: 42,Key: 'Key 43' Value: 43,Key: 'Key 44' Value: 44,Key: 'Key 45' Value: 45,Key: 'Key 46' Value: 46,Key: 'Key 47' Value: 47,Key: 'Key 48' Value: 48,Key: 'Key 49' Value: 49,Key: 'Key 5' Value: 5,Key: 'Key 50' Value: 50,Key: 'Key 51' Value: 51,Key: 'Key 52' Value: 52,Key: 'Key 53' Value: 53,Key: 'Key 54' Value: 54,Key: 'Key 55' Value: 55,Key: 'Key 56' Value: 56,Key: 'Key 57' Value: 57,Key: 'Key 58' Value: 58,Key: 'Key 59' Value: 59,Key: 'Key 6' Value: 6,Key: 'Key 60' Value: 60,Key: 'Key 61' Value: 61,Key: 'Key 62' Value: 62,Key: 'Key 63' Value: 63,Key: 'Key 64' Value: 64,Key: 'Key 65' Value: 65,Key: 'Key 66' Value: 66,Key: 'Key 67' Value: 67,Key: 'Key 68' Value: 68,Key: 'Key 69' Value: 69,Key: 'Key 7' Value: 7,Key: 'Key 70' Value: 70,Key: 'Key 71' Value: 71,Key: 'Key 72' Value: 72,Key: 'Key 73' Value: 73,Key: 'Key 74' Value: 74,Key: 'Key 75' Value: 75,Key: 'Key 76' Value: 76,Key: 'Key 77' Value: 77,Key: 'Key 78' Value: 78,Key: 'Key 79' Value: 79,Key: 'Key 8' Value: 8,Key: 'Key 80' Value: 80,Key: 'Key 81' Value: 81,Key: 'Key 82' Value: 82,Key: 'Key 83' Value: 83,Key: 'Key 84' Value: 84,Key: 'Key 85' Value: 85,Key: 'Key 86' Value: 86,Key: 'Key 87' Value: 87,Key: 'Key 88' Value: 88,Key: 'Key 89' Value: 89,Key: 'Key 9' Value: 9,Key: 'Key 90' Value: 90,Key: 'Key 91' Value: 91,Key: 'Key 92' Value: 92,Key: 'Key 93' Value: 93,Key: 'Key 94' Value: 94,Key: 'Key 95' Value: 95,Key: 'Key 96' Value: 96,Key: 'Key 97' Value: 97,Key: 'Key 98' Value: 98,Key: 'Key 99' Value: 99
Key: 'Key 0' Value: 0,Key: 'Key 1' Value: 1,Key: 'Key 10' Value: 10,Key: 'Key 11' Value: 11,Key: 'Key 12' Value: 12,Key: 'Key 13' Value: 13,Key: 'Key 14' Value: 14,Key: 'Key 15' Value: 15,Key: 'Key 16' Value: 16,Key: 'Key 17' Value: 17,Key: 'Key 18' Value: 18,Key: 'Key 19' Value: 19,Key: 'Key 2' Value: 2,Key: 'Key 20' Value: 20,Key: 'Key 21' Value: 21,Key: 'Key 22' Value: 22,Key: 'Key 23' Value: 23,Key: 'Key 24' Value: 24,Key: 'Key 25' Value: 25,Key: 'Key 26' Value: 26,Key: 'Key 27' Value: 27,Key: 'Key 28' Value: 28,Key: 'Key 29' Value: 29,Key: 'Key 3' Value: 3,Key: 'Key 30' Value: 30,Key: 'Key 31' Value: 31,Key: 'Key 32' Value: 32,Key: 'Key 33' Value: 33,Key: 'Key 34' Value: 34,Key: 'Key 35' Value: 35,Key: 'Key 36' Value: 36,Key: 'Key 37' Value: 37,Key: 'Key 38' Value: 38,Key: 'Key 39' Value: 39,Key: 'Key 4' Value: 4,Key: 'Key 40' Value: 40,Key: 'Key 41' Value: 41,Key: 'Key 42' Value: 42,Key: 'Key 43' Value: 43,Key: 'Key 44' Value: 44,Key: 'Key 45' Value: 45,Key: 'Key 46' Value: 46,Key: 'Key 47' Value: 47,Key: 'Key 48' Value: 48,Key: 'Key 49' Value: 49,Key: 'Key 5' Value: 5,Key: 'Key 50' Value: 50,Key: 'Key 51' Value: 51,Key: 'Key 52' Value: 52,Key: 'Key 53' Value: 53,Key: 'Key 54' Value: 54,Key: 'Key 55' Value: 55,Key: 'Key 56' Value: 56,Key: 'Key 57' Value: 57,Key: 'Key 58' Value: 58,Key: 'Key 59' Value: 59,Key: 'Key 6' Value: 6,Key: 'Key 60' Value: 60,Key: 'Key 61' Value: 61,Key: 'Key 62' Value: 62,Key: 'Key 63' Value: 63,Key: 'Key 64' Value: 64,Key: 'Key 65' Value: 65,Key: 'Key 66' Value: 66,Key: 'Key 67' Value: 67,Key: 'Key 68' Value: 68,Key: 'Key 69' Value: 69,Key: 'Key 7' Value: 7,Key: 'Key 70' Value: 70,Key: 'Key 71' Value: 71,Key: 'Key 72' Value: 72,Key: 'Key 73' Value: 73,Key: 'Key 74' Value: 74,Key: 'Key 75' Value: 75,Key: 'Key 76' Value: 76,Key: 'Key 77' Value: 77,Key: 'Key 78' Value: 78,Key: 'Key 79' Value: 79,Key: 'Key 8' Value: 8,Key: 'Key 80' Value: 80,Key: 'Key 81' Value: 81,Key: 'Key 82' Value: 82,Key: 'Key 83' Value: 83,Key: 'Key 84' Value: 84,Key: 'Key 85' Value: 85,Key: 'Key 86' Value: 86,Key: 'Key 87' Value: 87,Key: 'Key 88' Value: 88,Key: 'Key 89' Value: 89,Key: 'Key 9' Value: 9,Key: 'Key 90' Value: 90,Key: 'Key 91' Value: 91,Key: 'Key 92' Value: 92,Key: 'Key 93' Value: 93,Key: 'Key 94' Value: 94,Key: 'Key 95' Value: 95,Key: 'Key 96' Value: 96,Key: 'Key 97' Value: 97,Key: 'Key 98' Value: 98,Key: 'Key 99' Value: 99
Testing Dictionary nested iteration
Seen main: 100
Seen sub: 100
Key: 'Key 0' Value: 0,Key: 'Key 1' Value: 1,Key: 'Key 10' Value: 10,Key: 'Key 11' Value: 11,Key: 'Key 12' Value: 12,Key: 'Key 13' Value: 13,Key: 'Key 14' Value: 14,Key: 'Key 15' Value: 15,Key: 'Key 16' Value: 16,Key: 'Key 17' Value: 17,Key: 'Key 18' Value: 18,Key: 'Key 19' Value: 19,Key: 'Key 2' Value: 2,Key: 'Key 20' Value: 20,Key: 'Key 21' Value: 21,Key: 'Key 22' Value: 22,Key: 'Key 23' Value: 23,Key: 'Key 24' Value: 24,Key: 'Key 25' Value: 25,Key: 'Key 26' Value: 26,Key: 'Key 27' Value: 27,Key: 'Key 28' Value: 28,Key: 'Key 29' Value: 29,Key: 'Key 3' Value: 3,Key: 'Key 30' Value: 30,Key: 'Key 31' Value: 31,Key: 'Key 32' Value: 32,Key: 'Key 33' Value: 33,Key: 'Key 34' Value: 34,Key: 'Key 35' Value: 35,Key: 'Key 36' Value: 36,Key: 'Key 37' Value: 37,Key: 'Key 38' Value: 38,Key: 'Key 39' Value: 39,Key: 'Key 4' Value: 4,Key: 'Key 40' Value: 40,Key: 'Key 41' Value: 41,Key: 'Key 42' Value: 42,Key: 'Key 43' Value: 43,Key: 'Key 44' Value: 44,Key: 'Key 45' Value: 45,Key: 'Key 46' Value: 46,Key: 'Key 47' Value: 47,Key: 'Key 48' Value: 48,Key: 'Key 49' Value: 49,Key: 'Key 5' Value: 5,Key: 'Key 50' Value: 50,Key: 'Key 51' Value: 51,Key: 'Key 52' Value: 52,Key: 'Key 53' Value: 53,Key: 'Key 54' Value: 54,Key: 'Key 55' Value: 55,Key: 'Key 56' Value: 56,Key: 'Key 57' Value: 57,Key: 'Key 58' Value: 58,Key: 'Key 59' Value: 59,Key: 'Key 6' Value: 6,Key: 'Key 60' Value: 60,Key: 'Key 61' Value: 61,Key: 'Key 62' Value: 62,Key: 'Key 63' Value: 63,Key: 'Key 64' Value: 64,Key: 'Key 65' Value: 65,Key: 'Key 66' Value: 66,Key: 'Key 67' Value: 67,Key: 'Key 68' Value: 68,Key: 'Key 69' Value: 69,Key: 'Key 7' Value: 7,Key: 'Key 70' Value: 70,Key: 'Key 71' Value: 71,Key: 'Key 72' Value: 72,Key: 'Key 73' Value: 73,Key: 'Key 74' Value: 74,Key: 'Key 75' Value: 75,Key: 'Key 76' Value: 76,Key: 'Key 77' Value: 77,Key: 'Key 78' Value: 78,Key: 'Key 79' Value: 79,Key: 'Key 8' Value: 8,Key: 'Key 80' Value: 80,Key: 'Key 81' Value: 81,Key: 'Key 82' Value: 82,Key: 'Key 83' Value: 83,Key: 'Key 84' Value: 84,Key: 'Key 85' Value: 85,Key: 'Key 86' Value: 86,Key: 'Key 87' Value: 87,Key: 'Key 88' Value: 88,Key: 'Key 89' Value: 89,Key: 'Key 9' Value: 9,Key: 'Key 90' Value: 90,Key: 'Key 91' Value: 91,Key: 'Key 92' Value: 92,Key: 'Key 93' Value: 93,Key: 'Key 94' Value: 94,Key: 'Key 95' Value: 95,Key: 'Key 96' Value: 96,Key: 'Key 97' Value: 97,Key: 'Key 98' Value: 98,Key: 'Key 99' Value: 99
Key: 'Key 0' Value: 0,Key: 'Key 1' Value: 1,Key: 'Key 10' Value: 10,Key: 'Key 11' Value: 11,Key: 'Key 12' Value: 12,Key: 'Key 13' Value: 13,Key: 'Key 14' Value: 14,Key: 'Key 15' Value: 15,Key: 'Key 16' Value: 16,Key: 'Key 17' Value: 17,Key: 'Key 18' Value: 18,Key: 'Key 19' Value: 19,Key: 'Key 2' Value: 2,Key: 'Key 20' Value: 20,Key: 'Key 21' Value: 21,Key: 'Key 22' Value: 22,Key: 'Key 23' Value: 23,Key: 'Key 24' Value: 24,Key: 'Key 25' Value: 25,Key: 'Key 26' Value: 26,Key: 'Key 27' Value: 27,Key: 'Key 28' Value: 28,Key: 'Key 29' Value: 29,Key: 'Key 3' Value: 3,Key: 'Key 30' Value: 30,Key: 'Key 31' Value: 31,Key: 'Key 32' Value: 32,Key: 'Key 33' Value: 33,Key: 'Key 34' Value: 34,Key: 'Key 35' Value: 35,Key: 'Key 36' Value: 36,Key: 'Key 37' Value: 37,Key: 'Key 38' Value: 38,Key: 'Key 39' Value: 39,Key: 'Key 4' Value: 4,Key: 'Key 40' Value: 40,Key: 'Key 41' Value: 41,Key: 'Key 42' Value: 42,Key: 'Key 43' Value: 43,Key: 'Key 44' Value: 44,Key: 'Key 45' Value: 45,Key: 'Key 46' Value: 46,Key: 'Key 47' Value: 47,Key: 'Key 48' Value: 48,Key: 'Key 49' Value: 49,Key: 'Key 5' Value: 5,Key: 'Key 50' Value: 50,Key: 'Key 51' Value: 51,Key: 'Key 52' Value: 52,Key: 'Key 53' Value: 53,Key: 'Key 54' Value: 54,Key: 'Key 55' Value: 55,Key: 'Key 56' Value: 56,Key: 'Key 57' Value: 57,Key: 'Key 58' Value: 58,Key: 'Key 59' Value: 59,Key: 'Key 6' Value: 6,Key: 'Key 60' Value: 60,Key: 'Key 61' Value: 61,Key: 'Key 62' Value: 62,Key: 'Key 63' Value: 63,Key: 'Key 64' Value: 64,Key: 'Key 65' Value: 65,Key: 'Key 66' Value: 66,Key: 'Key 67' Value: 67,Key: 'Key 68' Value: 68,Key: 'Key 69' Value: 69,Key: 'Key 7' Value: 7,Key: 'Key 70' Value: 70,Key: 'Key 71' Value: 71,Key: 'Key 72' Value: 72,Key: 'Key 73' Value: 73,Key: 'Key 74' Value: 74,Key: 'Key 75' Value: 75,Key: 'Key 76' Value: 76,Key: 'Key 77' Value: 77,Key: 'Key 78' Value: 78,Key: 'Key 79' Value: 79,Key: 'Key 8' Value: 8,Key: 'Key 80' Value: 80,Key: 'Key 81' Value: 81,Key: 'Key 82' Value: 82,Key: 'Key 83' Value: 83,Key: 'Key 84' Value: 84,Key: 'Key 85' Value: 85,Key: 'Key 86' Value: 86,Key: 'Key 87' Value: 87,Key: 'Key 88' Value: 88,Key: 'Key 89' Value: 89,Key: 'Key 9' Value: 9,Key: 'Key 90' Value: 90,Key: 'Key 91' Value: 91,Key: 'Key 92' Value: 92,Key: 'Key 93' Value: 93,Key: 'Key 94' Value: 94,Key: 'Key 95' Value: 95,Key: 'Key 96' Value: 96,Key: 'Key 97' Value: 97,Key: 'Key 98' Value: 98,Key: 'Key 99' Value: 99

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
num_ticks = 1