Skip to content

Commit 97d9d8e

Browse files
committed
Fix jshPopIOEventOfType when the event to be popped is right at the start
1 parent 008f95b commit 97d9d8e

File tree

3 files changed

+34
-12
lines changed

3 files changed

+34
-12
lines changed

ChangeLog

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Date: fix parsing of ISO8601 timezones (+HHMM worked, but +HH:MM and +HH added) (fix #2669)
1010
Bangle.js1: dump() now doesn't write out interpreter state as JS (saves 1.5kB Flash)
1111
Espruino Pico: Removed 'tv' library by default to free up flash storage
12+
Fix jshPopIOEventOfType when the event to be popped is right at the start
1213

1314
2v28 : Add `E.internal` as a way to access the 'hidden root' containing Espruino internal variables that previously needed `global["\xff"]`
1415
Bangle.js: Fix back handler not removed when using E.setUI with a back button but without widgets (#2636)

src/jsdevices.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -570,12 +570,25 @@ void CALLED_FROM_INTERRUPT jshPushIOEvent(
570570
jshPushEvent(channel, (uint8_t*)&t, 4);
571571
}
572572

573+
/// Debugging only - prints the IO buffer, one item per line
574+
void jshDumpIOEvents() {
575+
for (int i=ioTail;;i++) {
576+
const char *name = "";
577+
if (i==ioHead) name = (i==ioLastHead) ? "ioHead + ioLastHead" : "ioHead";
578+
else if (i==ioLastHead) name = "ioLastHead";
579+
if (i==ioTail) name = "ioTail";
580+
jsiConsolePrintf("%d: %d %s\n", i, ioBuffer[i], name);
581+
if (i==ioHead) break;
582+
}
583+
}
584+
573585
// pop an IO event, returns EV_NONE on failure
574586
IOEventFlags jshPopIOEvent(uint8_t *data, unsigned int *length) {
575587
if (ioHead==ioTail) return EV_NONE;
576588
if (ioLastHead==ioTail) ioLastHead = ioHead; // if we're processing last head now, reset it
577589
IOBufferIdx idx = ioTail;
578590
unsigned int len = (unsigned int)ioBuffer[idx];
591+
assert(len <= IOEVENT_MAX_LEN);
579592
idx = (IOBufferIdx)((idx+1) & IOBUFFERMASK);
580593
IOEventFlags evt = (IOEventFlags)ioBuffer[idx];
581594
idx = (IOBufferIdx)((idx+1) & IOBUFFERMASK);
@@ -594,6 +607,7 @@ IOEventFlags jshPopIOEventOfType(IOEventFlags eventType, uint8_t *data, unsigned
594607
IOBufferIdx i = ioTail;
595608
while (ioHead!=i) {
596609
uint32_t len = (uint32_t)ioBuffer[i];
610+
assert(len <= IOEVENT_MAX_LEN);
597611
IOBufferIdx j = (IOBufferIdx)((i+1) & IOBUFFERMASK);
598612
IOEventFlags evt = (IOEventFlags)ioBuffer[j];
599613
if (IOEVENTFLAGS_GETTYPE(evt) == eventType) {
@@ -608,19 +622,23 @@ IOEventFlags jshPopIOEventOfType(IOEventFlags eventType, uint8_t *data, unsigned
608622
if (data) data[n] = ioBuffer[j];
609623
j = (IOBufferIdx)((j+1) & IOBUFFERMASK);
610624
}
611-
// work backwards and shift all items in queue down
612-
IOBufferIdx dst = (IOBufferIdx)((i+len+1) & IOBUFFERMASK); // to: last element of this event
613-
IOBufferIdx src = (IOBufferIdx)((i+IOBUFFERMASK) & IOBUFFERMASK); // from: item before current
614-
while (true) {
615-
ioBuffer[dst] = ioBuffer[src];
616-
if (src==ioTail)
617-
break;
618-
// move backwards
619-
src = (IOBufferIdx)((src+IOBUFFERMASK) & IOBUFFERMASK);
620-
dst = (IOBufferIdx)((dst+IOBUFFERMASK) & IOBUFFERMASK);
625+
if (i==ioTail) { // if we were at the start, just move onwards
626+
ioTail = j;
627+
} else { // not at the start, must shift back
628+
// work backwards and shift all items in queue down
629+
IOBufferIdx dst = (IOBufferIdx)((i+len+1) & IOBUFFERMASK); // to: last element of this event
630+
IOBufferIdx src = (IOBufferIdx)((i+IOBUFFERMASK) & IOBUFFERMASK); // from: item before current
631+
while (true) {
632+
ioBuffer[dst] = ioBuffer[src];
633+
if (src==ioTail)
634+
break;
635+
// move backwards
636+
src = (IOBufferIdx)((src+IOBUFFERMASK) & IOBUFFERMASK);
637+
dst = (IOBufferIdx)((dst+IOBUFFERMASK) & IOBUFFERMASK);
638+
}
639+
// finally update the tail pointer, and return
640+
ioTail = dst;
621641
}
622-
// finally update the tail pointer, and return
623-
ioTail = dst;
624642
ioLastHead = ioHead; // reset last head - if we're removing stuff in the middle it's easier not to optimise!
625643
jshInterruptOn();
626644
return evt;

src/jsdevices.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ void jshPushIOCharEvent(IOEventFlags channel, char ch);
200200
/// Push many character events at once (for example USB RX)
201201
void jshPushIOCharEvents(IOEventFlags channel, char *data, unsigned int count);
202202

203+
/// Debugging only - prints the IO buffer, one item per line
204+
void jshDumpIOEvents();
205+
203206
/// pop an IO event, returns EV_NONE on failure. data must be IOEVENT_MAX_LEN bytes
204207
IOEventFlags jshPopIOEvent(uint8_t *data, unsigned int *length);
205208
// pop an IO event of type eventType, returns event type on success,EV_NONE on failure. data must be IOEVENT_MAX_LEN bytes

0 commit comments

Comments
 (0)