fix: initialize stack frame params for all procedures

A previous change fixed compatibility with Scratch 2 removing 3's
unintentional scope leaking. This furthers that change so that
procedures with no parameters will also not accidentally use values in
other procedure stacks.
This commit is contained in:
Michael "Z" Goddard 2018-12-12 12:37:00 -05:00
parent 532e63da15
commit 20ff75b776
No known key found for this signature in database
GPG key ID: 762CD40DD5349872
5 changed files with 38 additions and 21 deletions

View file

@ -38,6 +38,7 @@ class Scratch3ProcedureBlocks {
const [paramNames, paramIds, paramDefaults] = paramNamesIdsAndDefaults;
util.initParams();
for (let i = 0; i < paramIds.length; i++) {
if (args.hasOwnProperty(paramIds[i])) {
util.pushParam(paramNames[i], args[paramIds[i]]);

View file

@ -170,6 +170,13 @@ class BlockUtility {
return this.thread.target.blocks.getProcedureParamNamesIdsAndDefaults(procedureCode);
}
/**
* Initialize procedure parameters in the thread before pushing parameters.
*/
initParams () {
this.thread.initParams();
}
/**
* Store a procedure parameter value by its name.
* @param {string} paramName The procedure's parameter name.

View file

@ -321,6 +321,16 @@ class Thread {
this.justReported = typeof value === 'undefined' ? null : value;
}
/**
* Initialize procedure parameters on this stack frame.
*/
initParams () {
const stackFrame = this.peekStackFrame();
if (stackFrame.params === null) {
stackFrame.params = {};
}
}
/**
* Add a parameter to the stack frame.
* Use when calling a procedure with parameter values.
@ -329,9 +339,6 @@ class Thread {
*/
pushParam (paramName, value) {
const stackFrame = this.peekStackFrame();
if (stackFrame.params === null) {
stackFrame.params = {};
}
stackFrame.params[paramName] = value;
}

Binary file not shown.

View file

@ -17,6 +17,7 @@ test('spec', t => {
t.type(th.peekStackFrame, 'function');
t.type(th.peekParentStackFrame, 'function');
t.type(th.pushReportedValue, 'function');
t.type(th.initParams, 'function');
t.type(th.pushParam, 'function');
t.type(th.peekStack, 'function');
t.type(th.getParam, 'function');
@ -107,6 +108,7 @@ test('peekStack', t => {
test('PushGetParam', t => {
const th = new Thread('arbitraryString');
th.pushStack('arbitraryString');
th.initParams();
th.pushParam('testParam', 'testValue');
t.strictEquals(th.peekStackFrame().params.testParam, 'testValue');
t.strictEquals(th.getParam('testParam'), 'testValue');