Skip to content

Commit b571122

Browse files
authored
fix: Mitigate crash on arrays of void or v128 (#2232)
1 parent 8047b02 commit b571122

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

src/compiler.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
getConstValueI64High,
4040
getConstValueF32,
4141
getConstValueF64,
42+
getConstValueV128,
4243
getBlockChildCount,
4344
getBlockChildAt,
4445
getBlockName,
@@ -193,6 +194,7 @@ import {
193194
writeI64,
194195
writeF32,
195196
writeF64,
197+
writeV128,
196198
uniqueMap,
197199
isPowerOf2,
198200
v128_zero,
@@ -1929,6 +1931,20 @@ export class Compiler extends DiagnosticEmitter {
19291931
}
19301932
break;
19311933
}
1934+
case <u32>TypeRef.V128: {
1935+
for (let i = 0; i < length; ++i) {
1936+
let value = values[i];
1937+
assert(getExpressionType(value) == elementTypeRef);
1938+
assert(getExpressionId(value) == ExpressionId.Const);
1939+
writeV128(getConstValueV128(value), buf, pos);
1940+
pos += 16;
1941+
}
1942+
break;
1943+
}
1944+
case <u32>TypeRef.None: {
1945+
// nothing to write
1946+
break;
1947+
}
19321948
default: assert(false);
19331949
}
19341950
return pos;
@@ -8269,11 +8285,15 @@ export class Compiler extends DiagnosticEmitter {
82698285
let elementExpression = expressions[i];
82708286
if (elementExpression.kind != NodeKind.OMITTED) {
82718287
let expr = this.compileExpression(<Expression>elementExpression, elementType, Constraints.CONV_IMPLICIT);
8272-
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
8273-
if (precomp) {
8274-
expr = precomp;
8275-
} else {
8288+
if (getExpressionType(expr) != elementType.toRef()) {
82768289
isStatic = false;
8290+
} else {
8291+
let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);
8292+
if (precomp) {
8293+
expr = precomp;
8294+
} else {
8295+
isStatic = false;
8296+
}
82778297
}
82788298
values[i] = expr;
82798299
} else {

src/module.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,6 +2665,17 @@ export function getConstValueF64(expr: ExpressionRef): f64 {
26652665
return binaryen._BinaryenConstGetValueF64(expr);
26662666
}
26672667

2668+
export function getConstValueV128(expr: ExpressionRef): Uint8Array {
2669+
let cArr = binaryen._malloc(16);
2670+
binaryen._BinaryenConstGetValueV128(expr, cArr);
2671+
let out = new Uint8Array(16);
2672+
for (let i = 0; i < 16; ++i) {
2673+
out[i] = binaryen.__i32_load8_u(cArr + i);
2674+
}
2675+
binaryen._free(cArr);
2676+
return out;
2677+
}
2678+
26682679
export function isConstZero(expr: ExpressionRef): bool {
26692680
if (getExpressionId(expr) != ExpressionId.Const) return false;
26702681
var type = getExpressionType(expr);

src/util/binary.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,14 @@ export function writeF64(value: f64, buffer: Uint8Array, offset: i32): void {
8787
writeI32(i64_low(valueI64), buffer, offset);
8888
writeI32(i64_high(valueI64), buffer, offset + 4);
8989
}
90+
91+
/** Reads a 128-bit vector from the specified buffer. */
92+
export function readV128(buffer: Uint8Array, offset: i32): Uint8Array {
93+
return buffer.slice(offset, offset + 16);
94+
}
95+
96+
/** Writes a 128-bit vector to the specified buffer. */
97+
export function writeV128(value: Uint8Array, buffer: Uint8Array, offset: i32): void {
98+
assert(value.length == 16);
99+
buffer.set(value, offset);
100+
}

0 commit comments

Comments
 (0)