Skip to content

Commit

Permalink
fit bitmask overflow initial dirty value in 'if' blocks (sveltejs#4507)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conduitry authored and taylorzane committed Dec 17, 2020
1 parent 1db1096 commit 4c4a41f
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* In `vars` array, correctly indicate whether `module` variables are `mutated` or `reassigned` ([#3215](https://github.com/sveltejs/svelte/issues/3215))
* Fix spread props not updating in certain situations ([#3521](https://github.com/sveltejs/svelte/issues/3521), [#4480](https://github.com/sveltejs/svelte/issues/4480))
* Use the fallback content for slots if they are passed only whitespace ([#4092](https://github.com/sveltejs/svelte/issues/4092))
* Fix bitmask overflow for `{#if}` blocks ([#4263](https://github.com/sveltejs/svelte/issues/4263))
* In `dev` mode, check for unknown props even if the component has no writable props ([#4323](https://github.com/sveltejs/svelte/issues/4323))
* Exclude global variables from `$capture_state` ([#4463](https://github.com/sveltejs/svelte/issues/4463))
* Fix bitmask overflow for slots ([#4481](https://github.com/sveltejs/svelte/issues/4481))
Expand Down
1 change: 1 addition & 0 deletions src/compiler/compile/render_dom/Renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 17 additions & 3 deletions src/compiler/compile/render_dom/wrappers/IfBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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};
`);

Expand Down Expand Up @@ -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);
}
`);
Expand Down Expand Up @@ -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';
},
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
24 changes: 24 additions & 0 deletions test/runtime/samples/bitmask-overflow-if/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default {
html: `
012345678910111213141516171819202122232425262728293031323334353637383940
expected: true
if: true
<button></button>
`,

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
<div></div>
<button></button>
`
);
}
};
62 changes: 62 additions & 0 deletions test/runtime/samples/bitmask-overflow-if/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script>
import { fade } from 'svelte/transition';
export let _a = [];
export let _0 = '0';
export let _1 = '1';
export let _2 = '2';
export let _3 = '3';
export let _4 = '4';
export let _5 = '5';
export let _6 = '6';
export let _7 = '7';
export let _8 = '8';
export let _9 = '9';
export let _10 = '10';
export let _11 = '11';
export let _12 = '12';
export let _13 = '13';
export let _14 = '14';
export let _15 = '15';
export let _16 = '16';
export let _17 = '17';
export let _18 = '18';
export let _19 = '19';
export let _20 = '20';
export let _21 = '21';
export let _22 = '22';
export let _23 = '23';
export let _24 = '24';
export let _25 = '25';
export let _26 = '26';
export let _27 = '27';
export let _28 = '28';
export let _29 = '29';
export let _30 = '30';
export let _31 = '31';
export let _32 = '32';
export let _33 = '33';
export let _34 = '34';
export let _35 = '35';
export let _36 = '36';
export let _37 = '37';
export let _38 = '38';
export let _39 = '39';
export let _40 = '40';
function update() {
_0 = '1';
}
</script>


{_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
<div out:fade></div>
{/if}

<button on:click={update}></button>

0 comments on commit 4c4a41f

Please sign in to comment.