diff --git a/src/compiler/compile/render_dom/Renderer.ts b/src/compiler/compile/render_dom/Renderer.ts index fbb0c76d7d5d..25012792143e 100644 --- a/src/compiler/compile/render_dom/Renderer.ts +++ b/src/compiler/compile/render_dom/Renderer.ts @@ -230,6 +230,7 @@ export default class Renderer { return bitmask; }; + // TODO: context-overflow make it less gross return { // Using a ParenthesizedExpression allows us to create // the expression lazily. TODO would be better if diff --git a/src/compiler/compile/render_dom/wrappers/IfBlock.ts b/src/compiler/compile/render_dom/wrappers/IfBlock.ts index dfc2228bc5e7..0506c943f92f 100644 --- a/src/compiler/compile/render_dom/wrappers/IfBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/IfBlock.ts @@ -288,7 +288,7 @@ export default class IfBlockWrapper extends Wrapper { } block.chunks.init.push(b` - let ${current_block_type} = ${select_block_type}(#ctx, -1); + let ${current_block_type} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}); let ${name} = ${get_block}; `); @@ -407,12 +407,12 @@ export default class IfBlockWrapper extends Wrapper { if (has_else) { block.chunks.init.push(b` - ${current_block_type_index} = ${select_block_type}(#ctx, -1); + ${current_block_type_index} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}); ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); `); } else { block.chunks.init.push(b` - if (~(${current_block_type_index} = ${select_block_type}(#ctx, -1))) { + if (~(${current_block_type_index} = ${select_block_type}(#ctx, ${this.get_initial_dirty_bit()}))) { ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#ctx); } `); @@ -587,4 +587,18 @@ export default class IfBlockWrapper extends Wrapper { `); } } + + get_initial_dirty_bit() { + const _this = this; + // TODO: context-overflow make it less gross + + const val = x`-1`; + return { + ...val, + elements: [val], + get type() { + return _this.renderer.context_overflow ? 'ArrayExpression' : 'UnaryExpression'; + }, + }; + } } diff --git a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts index 9ab48dd035e8..0f28689df312 100644 --- a/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts +++ b/src/compiler/compile/render_dom/wrappers/shared/get_slot_definition.ts @@ -63,7 +63,7 @@ export function get_slot_definition(block: Block, scope: TemplateScope, lets: Le const { context_lookup } = block.renderer; // i am well aware that this code is gross - // TODO make it less gross + // TODO: context-overflow make it less gross const changes = { type: 'ParenthesizedExpression', get expression() { diff --git a/test/runtime/samples/bitmask-overflow-if/_config.js b/test/runtime/samples/bitmask-overflow-if/_config.js new file mode 100644 index 000000000000..74bc70d4144f --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-if/_config.js @@ -0,0 +1,24 @@ +export default { + html: ` + 012345678910111213141516171819202122232425262728293031323334353637383940 + expected: true + if: true + + `, + + async test({ assert, component, target, window }) { + const button = target.querySelector("button"); + await button.dispatchEvent(new window.MouseEvent("click")); + + assert.htmlEqual( + target.innerHTML, + ` + 112345678910111213141516171819202122232425262728293031323334353637383940 + expected: false + if: false +
+ + ` + ); + } +}; diff --git a/test/runtime/samples/bitmask-overflow-if/main.svelte b/test/runtime/samples/bitmask-overflow-if/main.svelte new file mode 100644 index 000000000000..2c1c4530914f --- /dev/null +++ b/test/runtime/samples/bitmask-overflow-if/main.svelte @@ -0,0 +1,62 @@ + + + +{_0}{_1}{_2}{_3}{_4}{_5}{_6}{_7}{_8}{_9}{_10}{_11}{_12}{_13}{_14}{_15}{_16}{_17}{_18}{_19}{_20}{_21}{_22}{_23}{_24}{_25}{_26}{_27}{_28}{_29}{_30}{_31}{_32}{_33}{_34}{_35}{_36}{_37}{_38}{_39}{_40} + +expected: {_a.indexOf(_0) && _0 === '0' && _1 === '1'} +{#if _a.indexOf(_0) && _0 === '0' && _1 === '1'} +if: true +{:else} +if: false + +{/if} + + \ No newline at end of file