Skip to content

Commit 506f6e9

Browse files
Manual changes
1 parent 7c1dc39 commit 506f6e9

7 files changed

Lines changed: 48 additions & 36 deletions

File tree

src/interpreter/interpreter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ struct ExpressionInterpreter : OverriddenVisitor<ExpressionInterpreter, Flow> {
216216
WASM_UNREACHABLE("TODO");
217217
}
218218
}
219-
Flow visitSelect(Select* curr) { WASM_UNREACHABLE("TODO"); }
220219
Flow visitWideIntAddSub(WideIntAddSub* curr) { WASM_UNREACHABLE("TODO"); }
220+
Flow visitSelect(Select* curr) { WASM_UNREACHABLE("TODO"); }
221221
Flow visitDrop(Drop* curr) { WASM_UNREACHABLE("TODO"); }
222222
Flow visitReturn(Return* curr) { WASM_UNREACHABLE("TODO"); }
223223
Flow visitMemorySize(MemorySize* curr) { WASM_UNREACHABLE("TODO"); }

src/passes/Precompute.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -282,10 +282,6 @@ class PrecomputingExpressionRunner
282282
return Flow(NONCONSTANT_FLOW);
283283
}
284284

285-
Flow visitWideIntAddSub(WideIntAddSub* curr) {
286-
return Super::visitWideIntAddSub(curr);
287-
}
288-
289285
Flow visitStringEncode(StringEncode* curr) {
290286
// string.encode_wtf16_array is effectively an Array write operation, so
291287
// just like ArraySet and ArrayCopy above we must mark it as disallowed

src/support/stdckdint.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,22 @@ template<typename T> bool ckd_add(T* output, T a, T b) {
3838
#endif
3939
}
4040

41+
template<typename T> bool ckd_sub(T* output, T a, T b) {
42+
#if __has_builtin(__builtin_sub_overflow)
43+
return __builtin_sub_overflow(a, b, output);
44+
#else
45+
// Atm this polyfill only supports unsigned types.
46+
static_assert(std::is_unsigned_v<T>);
47+
48+
T result = a - b;
49+
if (result > a) {
50+
return true;
51+
}
52+
*output = result;
53+
return false;
54+
#endif
55+
}
56+
4157
} // namespace std
4258

4359
#endif // wasm_stdckdint_h

src/wasm-interpreter.h

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,18 +1808,25 @@ class ExpressionRunner : public OverriddenVisitor<SubType, Flow> {
18081808
uint64_t lowRHS = rightLow.getSingleValue().geti64();
18091809
uint64_t highRHS = rightHigh.getSingleValue().geti64();
18101810

1811-
uint64_t lowRes, highRes;
1812-
if (curr->op == AddInt128) {
1813-
lowRes = lowLHS + lowRHS;
1814-
highRes = highLHS + highRHS + (lowRes < lowLHS);
1815-
} else {
1816-
lowRes = lowLHS - lowRHS;
1817-
highRes = highLHS - highRHS - (lowLHS < lowRHS);
1811+
uint64_t lowResult = 0;
1812+
uint64_t highResult = 0;
1813+
1814+
switch (curr->op) {
1815+
case AddInt128: {
1816+
bool overflowed = std::ckd_add(&lowResult, lowLHS, lowRHS);
1817+
highResult = highLHS + highRHS + overflowed;
1818+
break;
1819+
}
1820+
case SubInt128: {
1821+
bool overflowed = std::ckd_sub(&lowResult, lowLHS, lowRHS);
1822+
highResult = highLHS - highRHS - overflowed;
1823+
break;
1824+
}
18181825
}
18191826

18201827
Literals results;
1821-
results.push_back(Literal(lowRes));
1822-
results.push_back(Literal(highRes));
1828+
results.push_back(Literal(lowResult));
1829+
results.push_back(Literal(highResult));
18231830
return results;
18241831
}
18251832
WASM_UNREACHABLE("invalid wide int binary op");
@@ -3074,9 +3081,6 @@ class ConstantExpressionRunner : public ExpressionRunner<SubType> {
30743081
Flow visitAtomicCmpxchg(AtomicCmpxchg* curr) {
30753082
return Flow(NONCONSTANT_FLOW);
30763083
}
3077-
Flow visitWideIntAddSub(WideIntAddSub* curr) {
3078-
return ExpressionRunner<SubType>::visitWideIntAddSub(curr);
3079-
}
30803084
Flow visitAtomicWait(AtomicWait* curr) { return Flow(NONCONSTANT_FLOW); }
30813085
Flow visitAtomicNotify(AtomicNotify* curr) { return Flow(NONCONSTANT_FLOW); }
30823086
Flow visitStructWait(StructWait* curr) { return Flow(NONCONSTANT_FLOW); }

src/wasm/wasm-stack.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,14 +2290,14 @@ void BinaryInstWriter::visitSelect(Select* curr) {
22902290
void BinaryInstWriter::visitWideIntAddSub(WideIntAddSub* curr) {
22912291
o << static_cast<int8_t>(BinaryConsts::MiscPrefix);
22922292
switch (curr->op) {
2293-
case AddInt128:
2293+
case AddInt128: {
22942294
o << U32LEB(BinaryConsts::I64Add128);
22952295
break;
2296-
case SubInt128:
2296+
}
2297+
case SubInt128: {
22972298
o << U32LEB(BinaryConsts::I64Sub128);
22982299
break;
2299-
default:
2300-
WASM_UNREACHABLE("invalid wide int binary op");
2300+
}
23012301
}
23022302
}
23032303

src/wasm/wasm-validator.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ struct ValidationInfo {
173173
return true;
174174
}
175175

176-
template<typename T, typename S>
176+
template<typename T>
177177
bool shouldBeEqualOrFirstIsUnreachable(
178-
S left, S right, T curr, const char* text, Function* func = nullptr) {
178+
Type left, Type right, T curr, const char* text, Function* func = nullptr) {
179179
if (left != Type::unreachable && left != right) {
180180
std::ostringstream ss;
181181
ss << left << " != " << right << ": " << text;
@@ -608,9 +608,9 @@ struct FunctionValidator : public WalkerPass<PostWalker<FunctionValidator>> {
608608
return info.shouldBeEqual(left, right, curr, text, getFunction());
609609
}
610610

611-
template<typename T, typename S>
611+
template<typename T>
612612
bool
613-
shouldBeEqualOrFirstIsUnreachable(S left, S right, T curr, const char* text) {
613+
shouldBeEqualOrFirstIsUnreachable(Type left, Type right, T curr, const char* text) {
614614
return info.shouldBeEqualOrFirstIsUnreachable(
615615
left, right, curr, text, getFunction());
616616
}
@@ -2443,19 +2443,16 @@ void FunctionValidator::visitSelect(Select* curr) {
24432443
}
24442444

24452445
void FunctionValidator::visitWideIntAddSub(WideIntAddSub* curr) {
2446-
if (!shouldBeTrue(getModule()->features.hasWideArithmetic(),
2446+
shouldBeTrue(getModule()->features.hasWideArithmetic(),
24472447
curr,
2448-
"Wide arithmetic is not enabled")) {
2449-
return;
2450-
}
2448+
"i64.add128 / i64.sub128 require wide arithmetic [--enable-wide-arithmetic]");
2449+
24512450
for (auto* operand :
24522451
{curr->leftLow, curr->leftHigh, curr->rightLow, curr->rightHigh}) {
2453-
if (operand->type != Type::unreachable) {
2454-
shouldBeEqual(operand->type,
2455-
Type(Type::i64),
2456-
curr,
2457-
"wide binary child types must be i64");
2458-
}
2452+
shouldBeEqualOrFirstIsUnreachable(operand->type,
2453+
Type(Type::BasicType::i64),
2454+
curr,
2455+
"wide binary child types must be i64");
24592456
}
24602457
}
24612458

test/spec/wide-arithmetic.wast

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
;;; --enable-wide-arithmetic
21
(module
32
(func (export "i64.add128") (param i64 i64 i64 i64) (result i64 i64)
43
local.get 0

0 commit comments

Comments
 (0)