TurboWarp / scratch-vm

Scratch VM with a JIT compiler and more features
https://turbowarp.org/
Mozilla Public License 2.0
75 stars 72 forks source link

Bug: `util.thread.peekStack()` is not working properly when there are nested reporters #171

Closed FurryR closed 11 months ago

FurryR commented 11 months ago

Expected Behavior

This might be a misunderstanding, but I'm very confused. I hope I can get some help.

For example,

func1 () {
  // command
}
func2 (args, util) {
  // reporter
  console.log(util.thread.stack); // util.thread.peekStack()
  return Cast.toNumber(args.VALUE);
}

then we use something like:

func1 (VALUE: func2(VALUE: 1))

Expected output: ["IDForFunc2"].

Actual Behavior

Actually, it outputs ["IDForFunc1"] in interpreter (normal) mode, and ["IDForFunc2"] in compiler mode (Source from Turbowarp, Gandi).

However util.peekStackFrame().op.id still equals to IDForFunc2 in interpreter mode (in compiler mode, util.peekStackFrame().op === null).

Steps to Reproduce

A quick example extension to reproduce:

(function (Scratch) {
  if (Scratch.vm.unsandboxed === false) throw new Error("This extension can only be used in unsandboxed mode.")
  class ExampleExtension {
    getInfo () {
      return {
        id: 'ExampleExtension',
        name: 'Example Extension',
        blocks: [
          { opcode: 'func1', blockType: Scratch.BlockType.COMMAND, text: 'func1 [value]', arguments: { value: { type: 'string' }}},
          { opcode: 'func2', blockType: Scratch.BlockType.REPORTER, text: 'func2 [value]', arguments: { value: { type: 'string' }}}
        ]
      };
    }
    func1 () {}
    func2 (args, util) {
      console.log(util.thread.stack);
      return args.value;
    }
  };
  Scratch.extensions.register(new ExampleExtension());
})(Scratch);

...and see the output.

Reproduced in: Original Scratch, ClipCC, Turbowarp, Gandi.

Operating System and Browser

Edge, Chromium, Firefox, etc.