ir: Fix variable cache collision when variable or list field has null ID
Fixes https://github.com/TurboWarp/scratch-vm/issues/239
This commit is contained in:
1 parent
36c02f3fec
commit
2c9d301da2
4 files changed
+83
-3
No files matched your search
@@ -1229,17 +1229,19 @@ class ScriptTreeGenerator {
|
||||
const variable = block.fields[fieldName];
|
||||
const id = variable.id;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(this.variableCache, id)) {
|
||||
if (id && Object.prototype.hasOwnProperty.call(this.variableCache, id)) {
|
||||
return this.variableCache[id];
|
||||
}
|
||||
|
||||
const data = this._descendVariable(id, variable.value, type);
|
||||
this.variableCache[id] = data;
|
||||
// If variable ID was null, this might do some unnecessary updates, but that is a rare
|
||||
// edge case and it won't have any adverse effects anyways.
|
||||
this.variableCache[data.id] = data;
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id The ID of the variable.
|
||||
* @param {string|null} id The ID of the variable.
|
||||
* @param {string} name The name of the variable.
|
||||
* @param {''|'list'} type The variable type.
|
||||
* @private
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,39 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: 99bb22ac4fb2542ce3c21fa7d2025f03d15392a33850585a4d12f4ec558663ac
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b2 = stage.variables[")|GMR5fz;%F_H,c0wGVM"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, "c", null);
|
||||
b1.value = 1;
|
||||
b2.value = 2;
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "check 1" }));
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "check 2" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "k", null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
if (((+b0.value || 0) === 1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass variable 1",}, b1, false, false, "m", null);
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables[")|GMR5fz;%F_H,c0wGVM"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
if (((+b0.value || 0) === 2)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass variable 2",}, b1, false, false, "q", null);
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// TW Snapshot
|
||||
// Input SHA-256: 99bb22ac4fb2542ce3c21fa7d2025f03d15392a33850585a4d12f4ec558663ac
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = runtime.getOpcodeFunction("looks_say");
|
||||
const b1 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b2 = stage.variables[")|GMR5fz;%F_H,c0wGVM"];
|
||||
return function* genXYZ () {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"plan 2",}, b0, false, false, "c", null);
|
||||
b1.value = 1;
|
||||
b2.value = 2;
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "check 1" }));
|
||||
yield* waitThreads(startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: "check 2" }));
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"end",}, b0, false, false, "k", null);
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables["`jEk@4|i[#Fk?(8x)AV.-my variable"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
if (((+b0.value || 0) === 1)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass variable 1",}, b1, false, false, "m", null);
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
|
||||
// Sprite1 script
|
||||
(function factoryXYZ(thread) { const target = thread.target; const runtime = target.runtime; const stage = runtime.getTargetForStage();
|
||||
const b0 = stage.variables[")|GMR5fz;%F_H,c0wGVM"];
|
||||
const b1 = runtime.getOpcodeFunction("looks_say");
|
||||
return function* genXYZ () {
|
||||
if (((+b0.value || 0) === 2)) {
|
||||
yield* executeInCompatibilityLayer({"MESSAGE":"pass variable 2",}, b1, false, false, "q", null);
|
||||
}
|
||||
retire(); return;
|
||||
}; })
|
||||
Reference in new issue
Block a user