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 +17 -6
- package/dist/jit.js.map +1 -1
- package/dist/jit_runtime.d.ts +3 -0
- package/dist/jit_runtime.js +34 -3
- package/dist/jit_runtime.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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.
|
|
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 (;;) {\
|
|
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
|
-
|
|
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
|
}
|