Add optional recursiveCall argument to execute

When execute calls itself to step into the next stack level, pass
RECURSIVE to the recursiveCall level. This argument provides
opportunity to recursed calls in execute to reduce the time needed for
some checks.

- Reduce time for checking around setting
  thread.requestScriptGlowInFrame
- Call thread.pushReportedValue at end of execute when in a recursive
  call

A boolean check is faster than a type lookup, command blocks will only
be executed in non-recursive calls. This saves a minor amount of time
for any result reporting blocks like blocks that get variables or add
two inputs together.

If the block is not returning a promise and execute is a recursed call,
that implies that the block is neither a hat or that the thread is not
at the top. That reduces handleReport to pushReportedValue. Using the
recursiveCall argument the final block calling handleReport can
shortcut the extra work in handleReport and reduce it to immediately
calling pushReportedValue.
This commit is contained in:
Michael "Z" Goddard 2018-01-24 14:44:07 -05:00
parent 6b7582f1c7
commit ab8d8e5f34
No known key found for this signature in database
GPG key ID: 762CD40DD5349872

View file

@ -98,12 +98,20 @@ const handleReport = function (
}
};
/**
* A convenienve constant to hide that the recursiveCall argument to execute is
* a boolean trap.
* @const {boolean}
*/
const RECURSIVE = true;
/**
* Execute a block.
* @param {!Sequencer} sequencer Which sequencer is executing.
* @param {!Thread} thread Thread which to read and execute.
* @param {boolean} recursiveCall is execute called from another execute call?
*/
const execute = function (sequencer, thread) {
const execute = function (sequencer, thread, recursiveCall) {
const runtime = sequencer.runtime;
const target = thread.target;
@ -202,7 +210,7 @@ const execute = function (sequencer, thread) {
// Save name of input for `Thread.pushReportedValue`.
currentStackFrame.waitingReporter = inputName;
// Actually execute the block.
execute(sequencer, thread);
execute(sequencer, thread, RECURSIVE);
if (thread.status === Thread.STATUS_PROMISE_WAIT) {
for (const _inputName in inputs) {
if (_inputName === inputName) break;
@ -291,7 +299,7 @@ const execute = function (sequencer, thread) {
runtime.profiler.records.push(runtime.profiler.STOP, performance.now());
}
if (typeof primitiveReportedValue === 'undefined') {
if (recursiveCall !== RECURSIVE && typeof primitiveReportedValue === 'undefined') {
// No value reported - potentially a command block.
// Edge-activated hats don't request a glow; all commands do.
thread.requestScriptGlowInFrame = true;
@ -338,7 +346,11 @@ const execute = function (sequencer, thread) {
thread.popStack();
});
} else if (thread.status === Thread.STATUS_RUNNING) {
handleReport(primitiveReportedValue, sequencer, thread, currentBlockId, opcode, isHat);
if (recursiveCall === RECURSIVE) {
thread.pushReportedValue(primitiveReportedValue);
} else {
handleReport(primitiveReportedValue, sequencer, thread, currentBlockId, opcode, isHat);
}
}
};