espruino / Espruino

The Espruino JavaScript interpreter - Official Repo
http://www.espruino.com/
Other
2.73k stars 741 forks source link

The following jit code doesn't seem to ever return #2433

Closed mariusGundersen closed 7 months ago

mariusGundersen commented 7 months ago

The following code hangs on my espruino pico v2.19:

const CHUNK_LENGTH = 10;
const lookup = new Uint8Array(256);
const chunk = new Uint8Array(CHUNK_LENGTH);
function streamDecompress(input, size, callback) {
  "jit";

  let l = 0;
  let c = 0;
  let o = 0;
  let repeat = 0;
  let actual = 0;
  let quad = 0;
  for (let i = 0; i < input.length;) {
    if (l < 256) {
      lookup[l++] = input[i++];
    } else if (o + c >= size) {
      return;
    } else if (repeat > 0) {
      chunk[c++] = input[i];
      repeat--;
      if (repeat === 0) i++;
    } else if (actual > 0) {
      chunk[c++] = input[i++];
      actual--;
    } else if (quad > 0) {
      chunk[c++] = lookup[(input[i] - 64) * 4 + 4 - quad];
      quad--;
      if (quad === 0) i++;
    } else if (input[i] < 0) {
      repeat = 1 - input[i++];
    } else if (input[i] >= 64) {
      quad = 4;
    } else {
      actual = 1 + input[i++];
    }

    if (c === CHUNK_LENGTH) {
      callback(chunk);
      c = 0;
      o += CHUNK_LENGTH;
    }
  }
}

const data = new Int8Array(258);
data[256] = 1 - 10;
data[257] = 5;

setTimeout(() => {
  console.log('decompressing');
  //should log 5,5,5,5,5,5,5,5,5,5
  streamDecompress(data, 10, data => console.log(data));
  console.log('done');
}, 10000);
console.log('ready');

The timeout is there so that you can reupload it again when it freezes.

I have tried to reduce it, but when I try it starts working. It works without "jit"; and it works with "compiled";.

gfwilliams commented 7 months ago

Ok, thanks - so you think it's size related? It could well be one of the jump instructions overflowed, or perhaps when a jump instruction overflows and ends up double-length it misaligns something else