From 5b36489095e40f993a5eefff06dd1b615337d6c1 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sun, 10 Nov 2019 16:10:26 -0500 Subject: [PATCH] helperise loop protection --- src/compiler/compile/Component.ts | 33 +++++++------- src/runtime/internal/dev.ts | 9 ++++ .../{loop_protect => loop-protect}/_config.js | 0 .../expected.js | 45 ++++++------------- .../input.svelte | 0 5 files changed, 38 insertions(+), 49 deletions(-) rename test/js/samples/{loop_protect => loop-protect}/_config.js (100%) rename test/js/samples/{loop_protect => loop-protect}/expected.js (63%) rename test/js/samples/{loop_protect => loop-protect}/input.svelte (100%) diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index aea7dc3f5e..b554a1be21 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -717,12 +717,12 @@ export default class Component { let scope = instance_scope; - const toRemove = []; + const to_remove = []; const remove = (parent, prop, index) => { - toRemove.unshift([parent, prop, index]); + to_remove.unshift([parent, prop, index]); }; - const toInsert = new Map(); + const to_insert = new Map(); walk(content, { enter(node, parent, prop, index) { @@ -760,10 +760,10 @@ export default class Component { }; } else { // can't insert directly, will screw up the index in the for-loop of estree-walker - if (!toInsert.has(parent)) { - toInsert.set(parent, []); + if (!to_insert.has(parent)) { + to_insert.set(parent, []); } - toInsert.get(parent).push(to_insert_for_loop_protect); + to_insert.get(parent).push(to_insert_for_loop_protect); } } } @@ -773,17 +773,17 @@ export default class Component { if (map.has(node)) { scope = scope.parent; } - if (toInsert.has(node)) { - const nodes_to_insert = toInsert.get(node); + if (to_insert.has(node)) { + const nodes_to_insert = to_insert.get(node); for (const { index, prop, node: node_to_insert } of nodes_to_insert.reverse()) { node[prop].splice(index, 0, node_to_insert); } - toInsert.delete(node); + to_insert.delete(node); } }, }); - for (const [parent, prop, index] of toRemove) { + for (const [parent, prop, index] of to_remove) { if (parent) { if (index !== null) { parent[prop].splice(index, 1); @@ -867,18 +867,15 @@ export default class Component { if (node.type === 'WhileStatement' || node.type === 'ForStatement' || node.type === 'DoWhileStatement') { - const id = this.get_unique_name('LP'); + const guard = this.get_unique_name('guard'); this.add_var({ - name: id.name, + name: guard.name, internal: true, }); - const before = b`const ${id} = Date.now();`; - const inside = b` - if (Date.now() - ${id} > 100) { - throw new Error('Infinite loop detected'); - } - `; + const before = b`const ${guard} = @loop_guard()`; + const inside = b`${guard}();`; + // wrap expression statement with BlockStatement if (node.body.type !== 'BlockStatement') { node.body = { diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 6e28d4045d..c10b339632 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -95,3 +95,12 @@ export class SvelteComponentDev extends SvelteComponent { }; } } + +export function loop_guard() { + const start = Date.now(); + return () => { + if (Date.now() - start > 100) { + throw new Error(`Infinite loop detected`); + } + }; +} \ No newline at end of file diff --git a/test/js/samples/loop_protect/_config.js b/test/js/samples/loop-protect/_config.js similarity index 100% rename from test/js/samples/loop_protect/_config.js rename to test/js/samples/loop-protect/_config.js diff --git a/test/js/samples/loop_protect/expected.js b/test/js/samples/loop-protect/expected.js similarity index 63% rename from test/js/samples/loop_protect/expected.js rename to test/js/samples/loop-protect/expected.js index 3119b4081c..bbb58c8194 100644 --- a/test/js/samples/loop_protect/expected.js +++ b/test/js/samples/loop-protect/expected.js @@ -3,6 +3,7 @@ import { SvelteComponentDev, dispatch_dev, init, + loop_guard, noop, safe_not_equal } from "svelte/internal"; @@ -34,44 +35,32 @@ function create_fragment(ctx) { } function instance($$self) { - const LP = Date.now(); + const guard = loop_guard(); while (true) { foo(); - - if (Date.now() - LP > 100) { - throw new Error("Infinite loop detected"); - } + guard(); } - const LP_1 = Date.now(); + const guard_1 = loop_guard(); for (; ; ) { foo(); - - if (Date.now() - LP_1 > 100) { - throw new Error("Infinite loop detected"); - } + guard_1(); } - const LP_2 = Date.now(); + const guard_2 = loop_guard(); while (true) { foo(); - - if (Date.now() - LP_2 > 100) { - throw new Error("Infinite loop detected"); - } + guard_2(); } - const LP_4 = Date.now(); + const guard_4 = loop_guard(); do { foo(); - - if (Date.now() - LP_4 > 100) { - throw new Error("Infinite loop detected"); - } + guard_4(); } while (true); $$self.$capture_state = () => { @@ -79,30 +68,24 @@ function instance($$self) { }; $$self.$inject_state = $$props => { - + }; $: { - const LP_3 = Date.now(); + const guard_3 = loop_guard(); while (true) { foo(); - - if (Date.now() - LP_3 > 100) { - throw new Error("Infinite loop detected"); - } + guard_3(); } } $: { - const LP_5 = Date.now(); + const guard_5 = loop_guard(); do { foo(); - - if (Date.now() - LP_5 > 100) { - throw new Error("Infinite loop detected"); - } + guard_5(); } while (true); } diff --git a/test/js/samples/loop_protect/input.svelte b/test/js/samples/loop-protect/input.svelte similarity index 100% rename from test/js/samples/loop_protect/input.svelte rename to test/js/samples/loop-protect/input.svelte