Skip to content

Commit 151ea30

Browse files
[mlir][Sol] Add support for remaining error handling built-ins
Signed-off-by: Vladimir Radosavljevic <vr@matterlabs.dev>
1 parent ce461be commit 151ea30

File tree

3 files changed

+44
-4
lines changed

3 files changed

+44
-4
lines changed

mlir/include/mlir/Dialect/Sol/SolOps.td

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,18 @@ def Sol_EmitOp : Sol_Op<"emit"> {
398398
}
399399

400400
def Sol_RevertOp : Sol_Op<"revert"> {
401-
let arguments = (ins Variadic<AnyType>:$args, StrAttr:$signature);
401+
// $signature represents the error call's signature if $call is set.
402+
let arguments = (ins Variadic<AnyType>:$args, StrAttr:$signature,
403+
UnitAttr:$call);
402404

403405
let assemblyFormat = "$signature ($args^ `:` type($args))? attr-dict";
404406
}
405407

408+
def Sol_AssertOp : Sol_Op<"assert"> {
409+
let arguments = (ins I1:$cond);
410+
let assemblyFormat = "$cond attr-dict";
411+
}
412+
406413
def Sol_RequireOp : Sol_Op<"require"> {
407414
// $msg represents the error call's signature if $call is set.
408415
let arguments = (ins I1:$cond, StrAttr:$msg,

mlir/lib/Conversion/SolToStandard/SolToStandardPass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ struct ConvertSolToStandardPass
149149
sol::RevertOp,
150150
sol::EmitOp,
151151
sol::RequireOp,
152+
sol::AssertOp,
152153
sol::ConvCastOp,
153154
sol::IfOp,
154155
sol::SwitchOp,

mlir/lib/Conversion/SolToStandard/SolToYul.cpp

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2252,6 +2252,26 @@ struct TryOpLowering : public OpConversionPattern<sol::TryOp> {
22522252
}
22532253
};
22542254

2255+
struct AssertOpLowering : public OpConversionPattern<sol::AssertOp> {
2256+
using OpConversionPattern<sol::AssertOp>::OpConversionPattern;
2257+
2258+
LogicalResult matchAndRewrite(sol::AssertOp op, OpAdaptor adaptor,
2259+
ConversionPatternRewriter &r) const override {
2260+
Location loc = op.getLoc();
2261+
evm::Builder evmB(r, loc);
2262+
2263+
// Generate: if (!cond) { panic(0x01) }
2264+
mlir::Value falseVal =
2265+
r.create<arith::ConstantIntOp>(loc, r.getI1Type(), 0);
2266+
mlir::Value negCond = r.create<arith::CmpIOp>(loc, arith::CmpIPredicate::eq,
2267+
op.getCond(), falseVal);
2268+
evmB.genPanic(evm::PanicCode::Assert, negCond);
2269+
2270+
r.eraseOp(op);
2271+
return success();
2272+
}
2273+
};
2274+
22552275
struct RequireOpLowering : public OpConversionPattern<sol::RequireOp> {
22562276
using OpConversionPattern<sol::RequireOp>::OpConversionPattern;
22572277

@@ -2333,8 +2353,20 @@ struct RevertOpLowering : public OpConversionPattern<sol::RevertOp> {
23332353
LogicalResult matchAndRewrite(sol::RevertOp op, OpAdaptor adaptor,
23342354
ConversionPatternRewriter &r) const override {
23352355
evm::Builder evmB(r, op.getLoc());
2336-
evmB.genRevert(op.getArgs().getTypes(), adaptor.getArgs(),
2337-
op.getSignature());
2356+
if (op.getCall()) {
2357+
// revert ErrorName(...)
2358+
assert(!op.getSignature().empty());
2359+
evmB.genRevert(op.getArgs().getTypes(), adaptor.getArgs(),
2360+
op.getSignature());
2361+
} else if (!op.getSignature().empty()) {
2362+
// revert("reason")
2363+
evmB.genRevertWithMsg(op.getSignature().str());
2364+
} else {
2365+
// revert()
2366+
mlir::solgen::BuilderExt bExt(r, op.getLoc());
2367+
mlir::Value zero = bExt.genI256Const(0);
2368+
r.create<yul::RevertOp>(op.getLoc(), zero, zero);
2369+
}
23382370
r.eraseOp(op);
23392371
return success();
23402372
}
@@ -3050,7 +3082,7 @@ void evm::populateEmitPat(RewritePatternSet &pats, TypeConverter &tyConv) {
30503082
}
30513083

30523084
void evm::populateRequirePat(RewritePatternSet &pats) {
3053-
pats.add<RequireOpLowering>(pats.getContext());
3085+
pats.add<RequireOpLowering, AssertOpLowering>(pats.getContext());
30543086
}
30553087

30563088
void evm::populateContractPat(RewritePatternSet &pats) {

0 commit comments

Comments
 (0)