pxt-common-packages 9.3.7 → 9.3.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -56,7 +56,7 @@ const pxsim_pxtrt = pxsim.pxtrt;
56
56
  const pxsim_numops = pxsim.numops;
57
57
 
58
58
 
59
- function _main___P133931(s) {
59
+ function _main___P133949(s) {
60
60
  let r0 = s.r0, step = s.pc;
61
61
  s.pc = -1;
62
62
 
@@ -66,19 +66,19 @@ if (yieldSteps-- < 0 && maybeYield(s, step, r0) || runtime !== pxsim.runtime) re
66
66
  switch (step) {
67
67
  case 0:
68
68
 
69
- globals._intervals___134172 = (undefined);
70
- globals._pollEventQueue___134185 = (undefined);
69
+ globals._intervals___134190 = (undefined);
70
+ globals._pollEventQueue___134203 = (undefined);
71
71
  r0 = undefined;
72
72
  return leave(s, r0)
73
73
  default: oops()
74
74
  } } }
75
- _main___P133931.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"colorbuffer.ts","functionName":"<main>","argumentNames":[]}
76
- _main___P133931.continuations = [ ]
75
+ _main___P133949.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"colorbuffer.ts","functionName":"<main>","argumentNames":[]}
76
+ _main___P133949.continuations = [ ]
77
77
 
78
- function _main___P133931_mk(s) {
78
+ function _main___P133949_mk(s) {
79
79
  checkStack(s.depth);
80
80
  return {
81
- parent: s, fn: _main___P133931, depth: s.depth + 1,
81
+ parent: s, fn: _main___P133949, depth: s.depth + 1,
82
82
  pc: 0, retval: undefined, r0: undefined, overwrittenPC: false, lambdaArgs: null,
83
83
  } }
84
84
 
@@ -88,5 +88,5 @@ function _main___P133931_mk(s) {
88
88
 
89
89
  const breakpoints = setupDebugger(1, [])
90
90
 
91
- return _main___P133931
91
+ return _main___P133949
92
92
  })
@@ -41,7 +41,9 @@ typedef Buffer Sound;
41
41
  typedef struct worker *worker_t;
42
42
  worker_t worker_alloc(const char *id, uint32_t stack_size);
43
43
  int worker_run(worker_t w, TaskFunction_t fn, void *arg);
44
+ int worker_run_wait(worker_t w, TaskFunction_t fn, void *arg);
44
45
  void worker_set_idle(worker_t w, TaskFunction_t fn, void *arg);
46
+ extern worker_t fg_worker;
45
47
 
46
48
  void memInfo();
47
49
 
@@ -240,41 +240,66 @@ int HF2::handlePkt(int sz) {
240
240
  return sendResponse(0);
241
241
  }
242
242
 
243
- void HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {
244
- if (!connected)
245
- return;
243
+ struct BufferEntry {
244
+ unsigned size;
245
+ uint8_t flag;
246
+ uint8_t data[0];
247
+ };
246
248
 
247
- uint32_t buf[64 / 4]; // aligned
249
+ static void send_buffer_core(void *ent_) {
250
+ auto ent = (BufferEntry *)ent_;
248
251
 
249
- if (prepend + 1)
250
- size += 4;
252
+ uint32_t buf[64 / 4]; // aligned
253
+ auto size = ent->size;
254
+ auto data = ent->data;
251
255
 
252
- while (connected && size > 0) {
256
+ while (hf2.connected && size > 0) {
253
257
  memset(buf + 1, 0, 60);
254
258
  int s = 63;
255
259
  if (size <= 63) {
256
260
  s = size;
257
- buf[0] = flag;
261
+ buf[0] = ent->flag;
258
262
  } else {
259
- buf[0] = flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : flag;
263
+ buf[0] = ent->flag == HF2_FLAG_CMDPKT_LAST ? HF2_FLAG_CMDPKT_BODY : ent->flag;
260
264
  }
261
265
  buf[0] |= s;
262
266
  uint8_t *dst = (uint8_t *)buf;
263
267
  dst++;
264
- if (prepend + 1) {
265
- memcpy(dst, &prepend, 4);
266
- prepend = -1;
267
- dst += 4;
268
- s -= 4;
269
- size -= 4;
270
- }
271
268
  memcpy(dst, data, s);
272
- data = (const uint8_t *)data + s;
269
+ data = data + s;
273
270
  size -= s;
274
271
 
275
- tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)buf, sizeof(buf));
272
+ if (tinyusb_cdcacm_write_queue(TINYUSB_CDC_ACM_0, (uint8_t *)buf, sizeof(buf)) <
273
+ sizeof(buf))
274
+ DMESG("CDC write fail");
276
275
  // tinyusb_cdcacm_write_flush(TINYUSB_CDC_ACM_0, 0); - prints warnings
277
276
  }
277
+
278
+ xfree(ent);
279
+ }
280
+
281
+ void HF2::sendBuffer(uint8_t flag, const void *data, unsigned size, uint32_t prepend) {
282
+ if (!connected)
283
+ return;
284
+
285
+ if (prepend + 1)
286
+ size += 4;
287
+
288
+ auto ent = (BufferEntry *)xmalloc(sizeof(BufferEntry) + size);
289
+ ent->size = size;
290
+ ent->flag = flag;
291
+ auto dst = ent->data;
292
+
293
+ if (prepend + 1) {
294
+ memcpy(dst, &prepend, 4);
295
+ dst += 4;
296
+ size -= 4;
297
+ }
298
+
299
+ memcpy(dst, data, size);
300
+
301
+ if (worker_run_wait(fg_worker, send_buffer_core, ent))
302
+ DMESG("HF2 queue full");
278
303
  }
279
304
 
280
305
  int HF2::sendEvent(uint32_t evId, const void *data, int size) {
@@ -48,4 +48,12 @@ int worker_run(worker_t w, TaskFunction_t fn, void *arg) {
48
48
  return -1;
49
49
  }
50
50
 
51
+ int worker_run_wait(worker_t w, TaskFunction_t fn, void *arg) {
52
+ qitem_t evt = {fn, arg};
53
+ if (xQueueSend(w->queue, &evt, 100) == pdPASS)
54
+ return 0;
55
+ return -1;
56
+ }
57
+
58
+
51
59
  }
@@ -147,6 +147,78 @@ static inline void runAction(FiberContext *ctx, RefAction *ra) {
147
147
  ctx->pc = actionPC(ra);
148
148
  }
149
149
 
150
+ static const uint8_t *find_src_map() {
151
+ const uint32_t *p = (const uint32_t *)((uint32_t)vmImg->dataEnd & ~0xf);
152
+ const uint32_t *endP = p + 128;
153
+ while (p < endP) {
154
+ if (p[0] == 0x4d435253 && p[1] == 0x2d4e1588 && p[2] == 0x719986aa)
155
+ return (const uint8_t *)p;
156
+ p += 4;
157
+ }
158
+ DMESG("source map not found; dataEnd=%p", vmImg->dataEnd);
159
+ return NULL;
160
+ }
161
+
162
+ static const uint8_t *decode_num(const uint8_t *p, int *dst) {
163
+ auto v = *p++;
164
+ if (v < 0xf0) {
165
+ *dst = v;
166
+ return p;
167
+ }
168
+ auto sz = v & 0x07;
169
+ int r = 0;
170
+ for (int i = 0; i < sz; ++i) {
171
+ r |= *p++ << (i * 8);
172
+ }
173
+ if (v & 0x08)
174
+ r = -r;
175
+ *dst = r;
176
+ return p;
177
+ }
178
+
179
+ static const uint8_t *dump_pc_one(int addr, int off, const uint8_t *fn) {
180
+ if (!fn)
181
+ return NULL;
182
+ auto p = fn;
183
+ while (*p)
184
+ p++;
185
+ p++;
186
+ int prevLn = 0, prevOff = 0;
187
+ while (*p != 0xff) {
188
+ int a, b, c;
189
+ p = decode_num(p, &a);
190
+ p = decode_num(p, &b);
191
+ p = decode_num(p, &c);
192
+ prevLn += a;
193
+ b <<= 1;
194
+ prevOff += b;
195
+ c <<= 1;
196
+
197
+ int startA = prevOff;
198
+ int endA = startA + c;
199
+ if (startA <= addr + off && addr + off <= endA) {
200
+ DMESG(" PC:%x %s(%d)", addr, fn, prevLn);
201
+ return NULL;
202
+ }
203
+ }
204
+ return p + 1;
205
+ }
206
+
207
+ static void dump_pc(int addr, const uint8_t *srcmap) {
208
+ if (srcmap) {
209
+ auto p = srcmap + 16;
210
+ for (;;) {
211
+ auto a = dump_pc_one(addr, -2, p);
212
+ if (!a || !dump_pc_one(addr, -4, p) || !dump_pc_one(addr, 0, p))
213
+ return;
214
+ p = a;
215
+ if (*p == 0)
216
+ break;
217
+ }
218
+ }
219
+ DMESG(" PC:%x", addr);
220
+ }
221
+
150
222
  void vm_stack_trace() {
151
223
  auto ctx = currentFiber;
152
224
  if (!ctx)
@@ -154,12 +226,13 @@ void vm_stack_trace() {
154
226
  DMESG("stack trace (programHash:%d):", programHash());
155
227
  auto end = vmImg->stackTop;
156
228
  auto ptr = ctx->sp;
157
- DMESG(" PC:%x", (ctx->pc - ctx->imgbase) << 1);
229
+ auto srcmap = find_src_map();
230
+ dump_pc((ctx->pc - ctx->imgbase) << 1, srcmap);
158
231
  int max = 30;
159
232
  while (ptr < end && max) {
160
233
  auto v = (uintptr_t)*ptr++;
161
234
  if (VM_IS_ENCODED_PC(v)) {
162
- DMESG(" PC:%x", VM_DECODE_PC(v) << 1);
235
+ dump_pc(VM_DECODE_PC(v) << 1, srcmap);
163
236
  max--;
164
237
  }
165
238
  }
@@ -218,18 +291,21 @@ void op_callind(FiberContext *ctx, unsigned arg) {
218
291
  void op_ret(FiberContext *ctx, unsigned arg) {
219
292
  SPLIT_ARG(retNumArgs, numTmps);
220
293
 
221
- // check if we're leaving a function that still has open try blocks
222
- // (this results from invalid code generation)
223
- if (ctx->tryFrame && ctx->tryFrame->registers[0] == (uintptr_t)ctx->currAction) {
224
- DMESG("try frame %p left on return", ctx->tryFrame);
225
- target_panic(PANIC_VM_ERROR);
226
- }
227
-
228
294
  POP(numTmps);
229
295
  auto retaddr = (intptr_t)POPVAL();
230
296
  ctx->currAction = (RefAction *)POPVAL();
231
297
  POP(retNumArgs);
232
298
 
299
+ // check if we're leaving a function that still has open try blocks
300
+ // (this results from invalid code generation)
301
+ if (ctx->tryFrame &&
302
+ ctx->tryFrame->registers[2] < (uint8_t *)ctx->sp - (uint8_t *)vmImg->stackBase) {
303
+ DMESG("try frame %p left on return %d/%d", ctx->tryFrame, ctx->tryFrame->registers[2],
304
+ (uint8_t *)ctx->sp - (uint8_t *)vmImg->stackBase);
305
+ vm_stack_trace();
306
+ target_panic(PANIC_VM_ERROR);
307
+ }
308
+
233
309
  if (retaddr == (intptr_t)TAG_STACK_BOTTOM) {
234
310
  ctx->pc = NULL;
235
311
  } else {