Skip to content

Commit bb5cf9a

Browse files
tanhauhauConduitry
authored andcommitted
fix: bitmask overflow better handle global (#4063)
1 parent 3e1e6cb commit bb5cf9a

File tree

3 files changed

+77
-27
lines changed

3 files changed

+77
-27
lines changed

src/compiler/compile/render_dom/Renderer.ts

+39-27
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ interface ContextMember {
1515
priority: number;
1616
}
1717

18+
type BitMasks = Array<{
19+
n: number;
20+
names: string[];
21+
}>;
22+
1823
export default class Renderer {
1924
component: Component; // TODO Maybe Renderer shouldn't know about Component?
2025
options: CompileOptions;
@@ -199,26 +204,29 @@ export default class Renderer {
199204
? x`$$self.$$.dirty`
200205
: x`#dirty`) as Identifier | MemberExpression;
201206

202-
const get_bitmask = () => names.reduce((bitmask, name) => {
203-
const member = renderer.context_lookup.get(name);
204-
205-
if (!member) return bitmask;
207+
let bitmask;
208+
const get_bitmask = () => {
209+
const bitmask: BitMasks = [];
210+
names.forEach((name) => {
211+
const member = renderer.context_lookup.get(name);
206212

207-
if (member.index.value === -1) {
208-
throw new Error(`unset index`);
209-
}
213+
if (!member) return;
210214

211-
const value = member.index.value as number;
212-
const i = (value / 31) | 0;
213-
const n = 1 << (value % 31);
215+
if (member.index.value === -1) {
216+
throw new Error(`unset index`);
217+
}
214218

215-
if (!bitmask[i]) bitmask[i] = { n: 0, names: [] };
219+
const value = member.index.value as number;
220+
const i = (value / 31) | 0;
221+
const n = 1 << (value % 31);
216222

217-
bitmask[i].n |= n;
218-
bitmask[i].names.push(name);
223+
if (!bitmask[i]) bitmask[i] = { n: 0, names: [] };
219224

225+
bitmask[i].n |= n;
226+
bitmask[i].names.push(name);
227+
});
220228
return bitmask;
221-
}, Array((this.context.length / 31) | 0).fill(null));
229+
};
222230

223231
let operator;
224232
let left;
@@ -231,21 +239,25 @@ export default class Renderer {
231239
// to lazily create the node. TODO would be better if
232240
// context was determined before rendering, so that
233241
// this indirection was unnecessary
234-
235-
const bitmask = get_bitmask();
236-
237-
if (renderer.context_overflow) {
238-
const expression = bitmask
239-
.map((b, i) => ({ b, i }))
240-
.filter(({ b }) => b)
241-
.map(({ b, i }) => x`${dirty}[${i}] & /*${b.names.join(', ')}*/ ${b.n}`)
242-
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`);
243-
244-
({ operator, left, right } = expression);
245-
} else {
246-
({ operator, left, right } = x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0] ? bitmask[0].n : 0}` as BinaryExpression); // TODO the `: 0` case should never apply
242+
if (!bitmask) {
243+
bitmask = get_bitmask();
244+
245+
if (!bitmask.length) {
246+
({ operator, left, right } = x`${dirty} & /*${names.join(', ')}*/ 0` as BinaryExpression);
247+
} else if (renderer.context_overflow) {
248+
const expression = bitmask
249+
.map((b, i) => ({ b, i }))
250+
.filter(({ b }) => b)
251+
.map(({ b, i }) => x`${dirty}[${i}] & /*${b.names.join(', ')}*/ ${b.n}`)
252+
.reduce((lhs, rhs) => x`${lhs} | ${rhs}`);
253+
254+
({ operator, left, right } = expression as BinaryExpression);
255+
} else {
256+
({ operator, left, right } = x`${dirty} & /*${names.join(', ')}*/ ${bitmask[0].n}` as BinaryExpression);
257+
}
247258
}
248259

260+
249261
return 'BinaryExpression';
250262
},
251263
get operator() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
error: `potato is not defined`,
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<script>
2+
export let x1;
3+
export let x2;
4+
export let x3;
5+
export let x4;
6+
export let x5;
7+
export let x6;
8+
export let x7;
9+
export let x8;
10+
export let x9;
11+
export let x10;
12+
export let x11;
13+
export let x12;
14+
export let x13;
15+
export let x14;
16+
export let x15;
17+
export let x16;
18+
export let x17;
19+
export let x18;
20+
export let x19;
21+
export let x20;
22+
export let x21;
23+
export let x22;
24+
export let x23;
25+
export let x24;
26+
export let x25;
27+
export let x26;
28+
export let x27;
29+
export let x28;
30+
export let x29;
31+
export let x30;
32+
export let x31;
33+
export let x32;
34+
</script>
35+
<p {...potato}>{x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + x26 + x27 + x28 + x29 + x30 + x31 + x32}</p>

0 commit comments

Comments
 (0)