Skip to content

Commit 4a7bb25

Browse files
committed
feat(slang): lower additional EVM intrinsics
Wire up `block.blobbasefee`, `block.difficulty`, `block.prevrandao`, `address.balance`, and `address.codehash` member accesses to their Sol dialect ops. The address-base intrinsics evaluate the operand expression and emit `sol.balance` / `sol.code_hash` with the resulting address value.
1 parent a26fbcd commit 4a7bb25

2 files changed

Lines changed: 59 additions & 8 deletions

File tree

  • solx-slang/src/ast/contract/function/expression

solx-slang/src/ast/contract/function/expression/call/mod.rs

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ use slang_solidity::backend::built_ins::BuiltIn;
1111
use slang_solidity::backend::ir::ast::ArgumentsDeclaration;
1212
use slang_solidity::backend::ir::ast::Expression;
1313
use slang_solidity::backend::ir::ast::FunctionCallExpression;
14+
use slang_solidity::backend::ir::ast::MemberAccessExpression;
15+
use solx_mlir::ods::sol::BalanceOperation;
1416
use solx_mlir::ods::sol::BaseFeeOperation;
17+
use solx_mlir::ods::sol::BlobBaseFeeOperation;
1518
use solx_mlir::ods::sol::BlockNumberOperation;
1619
use solx_mlir::ods::sol::CallValueOperation;
1720
use solx_mlir::ods::sol::CallerOperation;
1821
use solx_mlir::ods::sol::ChainIdOperation;
22+
use solx_mlir::ods::sol::CodeHashOperation;
1923
use solx_mlir::ods::sol::CoinbaseOperation;
24+
use solx_mlir::ods::sol::DifficultyOperation;
2025
use solx_mlir::ods::sol::GasLimitOperation;
2126
use solx_mlir::ods::sol::GasPriceOperation;
2227
use solx_mlir::ods::sol::OriginOperation;
28+
use solx_mlir::ods::sol::PrevRandaoOperation;
2329
use solx_mlir::ods::sol::TimestampOperation;
2430

2531
use crate::ast::contract::function::expression::ExpressionEmitter;
@@ -172,15 +178,51 @@ impl<'emitter, 'state, 'context, 'block> CallEmitter<'emitter, 'state, 'context,
172178
/// Returns an error if the member access is not a recognized EVM intrinsic.
173179
pub fn emit_member_access(
174180
&self,
175-
member_identifier: &slang_solidity::backend::ir::ast::Identifier,
181+
access: &MemberAccessExpression,
176182
block: BlockRef<'context, 'block>,
177183
) -> anyhow::Result<(Value<'context, 'block>, BlockRef<'context, 'block>)> {
184+
let member_identifier = access.member();
178185
let builder = &self.expression_emitter.state.builder;
179186
let context = builder.context;
180187
let location = builder.unknown_location;
181188
let address_type = builder.types.sol_address;
182189
let ui256_type = builder.types.ui256;
183-
let operation = match member_identifier.resolved_built_in() {
190+
let resolved_built_in = member_identifier.resolved_built_in();
191+
if let Some(BuiltIn::AddressBalance) = resolved_built_in {
192+
let operand = access.operand();
193+
let (address_value, current_block) =
194+
self.expression_emitter.emit_value(&operand, block)?;
195+
let value = current_block
196+
.append_operation(
197+
BalanceOperation::builder(context, location)
198+
.cont_addr(address_value)
199+
.out(ui256_type)
200+
.build()
201+
.into(),
202+
)
203+
.result(0)
204+
.expect("sol.balance always produces one result")
205+
.into();
206+
return Ok((value, current_block));
207+
}
208+
if let Some(BuiltIn::AddressCodehash) = resolved_built_in {
209+
let operand = access.operand();
210+
let (address_value, current_block) =
211+
self.expression_emitter.emit_value(&operand, block)?;
212+
let value = current_block
213+
.append_operation(
214+
CodeHashOperation::builder(context, location)
215+
.cont_addr(address_value)
216+
.out(ui256_type)
217+
.build()
218+
.into(),
219+
)
220+
.result(0)
221+
.expect("sol.code_hash always produces one result")
222+
.into();
223+
return Ok((value, current_block));
224+
}
225+
let operation = match resolved_built_in {
184226
Some(BuiltIn::TxOrigin) => OriginOperation::builder(context, location)
185227
.addr(address_type)
186228
.build()
@@ -221,6 +263,18 @@ impl<'emitter, 'state, 'context, 'block> CallEmitter<'emitter, 'state, 'context,
221263
.val(ui256_type)
222264
.build()
223265
.into(),
266+
Some(BuiltIn::BlockBlobbasefee) => BlobBaseFeeOperation::builder(context, location)
267+
.val(ui256_type)
268+
.build()
269+
.into(),
270+
Some(BuiltIn::BlockDifficulty) => DifficultyOperation::builder(context, location)
271+
.val(ui256_type)
272+
.build()
273+
.into(),
274+
Some(BuiltIn::BlockPrevrandao) => PrevRandaoOperation::builder(context, location)
275+
.val(ui256_type)
276+
.build()
277+
.into(),
224278
_ => anyhow::bail!("unsupported member access: {}", member_identifier.name()),
225279
};
226280
let value = block

solx-slang/src/ast/contract/function/expression/mod.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,9 @@ impl<'state, 'context, 'block> ExpressionEmitter<'state, 'context, 'block> {
289289
Expression::FunctionCallExpression(call) => {
290290
self::call::CallEmitter::new(self).emit_function_call(call, block)
291291
}
292-
Expression::MemberAccessExpression(access) => {
293-
let member = access.member();
294-
self::call::CallEmitter::new(self)
295-
.emit_member_access(&member, block)
296-
.map(|(value, block)| (Some(value), block))
297-
}
292+
Expression::MemberAccessExpression(access) => self::call::CallEmitter::new(self)
293+
.emit_member_access(access, block)
294+
.map(|(value, block)| (Some(value), block)),
298295
Expression::TupleExpression(tuple) => {
299296
let items = tuple.items();
300297
// TODO: support multi-value tuples (e.g. tuple deconstruction)

0 commit comments

Comments
 (0)