jseption 0.0.1 → 0.0.2

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.
package/dist/jit.js CHANGED
@@ -888,6 +888,9 @@ function P(code, kind, extra) {
888
888
  }
889
889
  return p;
890
890
  }
891
+ /* the interrupt poll emitted at every function entry and loop head: the interpreter's
892
+ counter, decremented in place (`$C` is the context); the handler is asked when it runs out */
893
+ const POLL = 'if (--$C.interrupt_counter <= 0) $RT.poll_handler();\n';
891
894
  const IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
892
895
  const RESERVED = new Set(['__proto__']);
893
896
  function fmt_number(n) {
@@ -2805,7 +2808,7 @@ class Relooper {
2805
2808
  const label = this.label('$L');
2806
2809
  const st = { kind: 'loop', label, entries: entrySet, nextEntries, nextIsMulti: nextEntries.size > 1 };
2807
2810
  const body = this.reloop(inner, entries, [...ctx, st], entrySet);
2808
- return `${label}: for (;;) {\n${body}\n}\n` + this.reloop(outer, [...nextEntries], ctx, loopEntries);
2811
+ return `${label}: for (;;) {\n${POLL}${body}\n}\n` + this.reloop(outer, [...nextEntries], ctx, loopEntries);
2809
2812
  }
2810
2813
  /* multiple */
2811
2814
  return this.emit_multiple(nodes, entries.map(e => ({ cond: `$l === ${e}`, entry: e })), ctx, loopEntries, '');
@@ -2905,7 +2908,7 @@ class Relooper {
2905
2908
  else {
2906
2909
  handler = `$RT.iterator_close_exc($s${r.slot - 2}); throw $e;`;
2907
2910
  }
2908
- const code = `${label}: try {\n${body}\n} catch ($e) {\n$e = $RT.to_guest_exception($e); ${handler}\n}\n`;
2911
+ const code = `${label}: try {\n${body}\n} catch ($e) {\n$e = $RT.catchable($e); ${handler}\n}\n`;
2909
2912
  return code + this.reloop(rest, [...nextEntries], ctx, loopEntries);
2910
2913
  }
2911
2914
  const blk = node.block;
@@ -2976,14 +2979,14 @@ class Relooper {
2976
2979
  else {
2977
2980
  handler = `$RT.iterator_close_exc($s${c.slot - 2}); throw $e;`;
2978
2981
  }
2979
- cases += `case ${id}: ${tl}: try {\n${body}\n} catch ($e) {\n$e = $RT.to_guest_exception($e); ${handler}\n}\ncontinue ${label};\n`;
2982
+ cases += `case ${id}: ${tl}: try {\n${body}\n} catch ($e) {\n$e = $RT.catchable($e); ${handler}\n}\ncontinue ${label};\n`;
2980
2983
  }
2981
2984
  else {
2982
2985
  const blk = node.block;
2983
2986
  cases += `case ${blk.id}: {\n${blk.code}${this.emit_term(blk, innerCtx, null)}\n}\n`;
2984
2987
  }
2985
2988
  }
2986
- return `$l = ${r.entry_node ?? r.entry.id};\n${label}: for (;;) {\nswitch ($l) {\n${cases}default: $RT.throw_internal_error("jit: bad state " + $l);\n}\n}\n`;
2989
+ return `$l = ${r.entry_node ?? r.entry.id};\n${label}: for (;;) {\n${POLL}switch ($l) {\n${cases}default: $RT.throw_internal_error("jit: bad state " + $l);\n}\n}\n`;
2987
2990
  }
2988
2991
  }
2989
2992
  /* used by the runtime adapter when compiled code creates a closure: the compiled form if the
@@ -3105,7 +3108,8 @@ export function jit_generate_source(ctx, b, id = 0, opts = {}) {
3105
3108
  params.push(`$a${i}`);
3106
3109
  fwparams.push(`$a${i}`);
3107
3110
  }
3108
- let prologue = '';
3111
+ /* every entry polls, as every loop head does: recursion can run unbounded without a back edge */
3112
+ let prologue = POLL;
3109
3113
  const natural = fi.natural;
3110
3114
  if (osr !== undefined) {
3111
3115
  /* replacement entry: the interpreter frame's state (cells for captured variables) */
@@ -3209,12 +3213,19 @@ ${prologue}${body}};
3209
3213
  };`;
3210
3214
  }
3211
3215
  /* the url names the function for host stack traces; its id leads to the position table */
3212
- source += `\n//# sourceURL=jseption:${id}:${jit_file_name(ctx, b)}:${name || '<anonymous>'}`;
3216
+ source += `\n//# sourceURL=jseption:${id}:${url_part(jit_file_name(ctx, b))}:${url_part(name || '<anonymous>')}`;
3213
3217
  const res = { source, name };
3214
3218
  if (osr !== undefined)
3215
3219
  res.osr = { arg_cell: fi.argCell.slice(), var_cell: fi.varCell.slice(), depth: cfg.byPc.get(osr).stateIn.length };
3216
3220
  return res;
3217
3221
  }
3222
+ /* a file or function name as it goes into the generated code's `sourceURL` comment: the file
3223
+ name is the embedder's and the function name the guest's, so a line terminator in either
3224
+ would end the comment and make the rest host code (a function declaration there is hoisted
3225
+ into the compiled code's scope). Control characters and line terminators become `_`. */
3226
+ function url_part(s) {
3227
+ return s.replace(/[\u0000-\u001f\u007f\u2028\u2029]/g, '_');
3228
+ }
3218
3229
  function jit_file_name(ctx, b) {
3219
3230
  return (b.has_debug && JS_AtomGetStr(ctx, b.debug.filename)) || '<eval>';
3220
3231
  }