constant_folding.rs 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. use super::cfg::{ControlFlowGraph, Instr};
  2. use super::reaching_definitions;
  3. use crate::parser::pt::Loc;
  4. use crate::sema::ast::{Builtin, Diagnostic, Expression, Namespace, StringLocation, Type};
  5. use num_bigint::{BigInt, Sign};
  6. use num_traits::{ToPrimitive, Zero};
  7. use ripemd160::Ripemd160;
  8. use sha2::{Digest, Sha256};
  9. use std::ops::{Add, BitAnd, BitOr, BitXor, Div, Mul, Rem, Shl, Shr, Sub};
  10. use tiny_keccak::{Hasher, Keccak};
  11. /// Constant folding pass on the given cfg. During constant folding, we may find issues
  12. /// like divide by zero, so this function returns a list of diagnostics which should
  13. /// be added to the namespace.
  14. pub fn constant_folding(cfg: &mut ControlFlowGraph, ns: &mut Namespace) {
  15. // for each block, instruction
  16. for block_no in 0..cfg.blocks.len() {
  17. let mut vars = cfg.blocks[block_no].defs.clone();
  18. for instr_no in 0..cfg.blocks[block_no].instr.len() {
  19. let cur = reaching_definitions::Def { block_no, instr_no };
  20. match &cfg.blocks[block_no].instr[instr_no] {
  21. Instr::Set { loc, res, expr, .. } => {
  22. let (expr, expr_constant) = expression(expr, Some(&vars), &cur, cfg, ns);
  23. if expr_constant {
  24. ns.var_constants.insert(*loc, expr.clone());
  25. }
  26. cfg.blocks[block_no].instr[instr_no] = Instr::Set {
  27. loc: *loc,
  28. res: *res,
  29. expr,
  30. };
  31. }
  32. Instr::Call {
  33. res,
  34. call,
  35. args,
  36. return_tys,
  37. } => {
  38. let args = args
  39. .iter()
  40. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  41. .collect();
  42. cfg.blocks[block_no].instr[instr_no] = Instr::Call {
  43. res: res.clone(),
  44. call: call.clone(),
  45. args,
  46. return_tys: return_tys.clone(),
  47. };
  48. }
  49. Instr::Return { value } => {
  50. let value = value
  51. .iter()
  52. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  53. .collect();
  54. cfg.blocks[block_no].instr[instr_no] = Instr::Return { value };
  55. }
  56. Instr::BranchCond {
  57. cond,
  58. true_block,
  59. false_block,
  60. } => {
  61. let (cond, _) = expression(cond, Some(&vars), &cur, cfg, ns);
  62. if let Expression::BoolLiteral(_, cond) = cond {
  63. cfg.blocks[block_no].instr[instr_no] = Instr::Branch {
  64. block: if cond { *true_block } else { *false_block },
  65. };
  66. } else {
  67. cfg.blocks[block_no].instr[instr_no] = Instr::BranchCond {
  68. cond,
  69. true_block: *true_block,
  70. false_block: *false_block,
  71. };
  72. }
  73. }
  74. Instr::Store { dest, pos } => {
  75. let (dest, _) = expression(dest, Some(&vars), &cur, cfg, ns);
  76. cfg.blocks[block_no].instr[instr_no] = Instr::Store { dest, pos: *pos };
  77. }
  78. Instr::AssertFailure { expr: Some(expr) } => {
  79. let (expr, _) = expression(expr, Some(&vars), &cur, cfg, ns);
  80. cfg.blocks[block_no].instr[instr_no] =
  81. Instr::AssertFailure { expr: Some(expr) };
  82. }
  83. Instr::Print { expr } => {
  84. let (expr, _) = expression(expr, Some(&vars), &cur, cfg, ns);
  85. cfg.blocks[block_no].instr[instr_no] = Instr::Print { expr };
  86. }
  87. Instr::ClearStorage { ty, storage } => {
  88. let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
  89. cfg.blocks[block_no].instr[instr_no] = Instr::ClearStorage {
  90. ty: ty.clone(),
  91. storage,
  92. };
  93. }
  94. Instr::SetStorage { ty, storage, value } => {
  95. let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
  96. let (value, _) = expression(value, Some(&vars), &cur, cfg, ns);
  97. cfg.blocks[block_no].instr[instr_no] = Instr::SetStorage {
  98. ty: ty.clone(),
  99. storage,
  100. value,
  101. };
  102. }
  103. Instr::SetStorageBytes {
  104. storage,
  105. value,
  106. offset,
  107. } => {
  108. let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
  109. let (value, _) = expression(value, Some(&vars), &cur, cfg, ns);
  110. let (offset, _) = expression(offset, Some(&vars), &cur, cfg, ns);
  111. cfg.blocks[block_no].instr[instr_no] = Instr::SetStorageBytes {
  112. storage,
  113. value,
  114. offset,
  115. };
  116. }
  117. Instr::PushStorage { storage, value } => {
  118. let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
  119. let (value, _) = expression(value, Some(&vars), &cur, cfg, ns);
  120. cfg.blocks[block_no].instr[instr_no] = Instr::PushStorage { storage, value };
  121. }
  122. Instr::PopStorage { res, storage } => {
  123. let (storage, _) = expression(storage, Some(&vars), &cur, cfg, ns);
  124. cfg.blocks[block_no].instr[instr_no] = Instr::PopStorage { res: *res, storage };
  125. }
  126. Instr::PushMemory {
  127. res,
  128. ty,
  129. array,
  130. value,
  131. } => {
  132. let (value, _) = expression(value, Some(&vars), &cur, cfg, ns);
  133. cfg.blocks[block_no].instr[instr_no] = Instr::PushMemory {
  134. res: *res,
  135. ty: ty.clone(),
  136. array: *array,
  137. value: Box::new(value),
  138. };
  139. }
  140. Instr::Constructor {
  141. success,
  142. res,
  143. contract_no,
  144. constructor_no,
  145. args,
  146. value,
  147. gas,
  148. salt,
  149. } => {
  150. let args = args
  151. .iter()
  152. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  153. .collect();
  154. let value = value
  155. .as_ref()
  156. .map(|expr| expression(expr, Some(&vars), &cur, cfg, ns).0);
  157. let gas = expression(gas, Some(&vars), &cur, cfg, ns).0;
  158. let salt = salt
  159. .as_ref()
  160. .map(|expr| expression(expr, Some(&vars), &cur, cfg, ns).0);
  161. cfg.blocks[block_no].instr[instr_no] = Instr::Constructor {
  162. success: *success,
  163. res: *res,
  164. contract_no: *contract_no,
  165. constructor_no: *constructor_no,
  166. args,
  167. value,
  168. gas,
  169. salt,
  170. };
  171. }
  172. Instr::ExternalCall {
  173. success,
  174. address,
  175. payload,
  176. args,
  177. value,
  178. gas,
  179. callty,
  180. } => {
  181. let args = args
  182. .iter()
  183. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  184. .collect();
  185. let value = expression(value, Some(&vars), &cur, cfg, ns).0;
  186. let gas = expression(gas, Some(&vars), &cur, cfg, ns).0;
  187. let payload = expression(payload, Some(&vars), &cur, cfg, ns).0;
  188. let address = address
  189. .as_ref()
  190. .map(|expr| expression(expr, Some(&vars), &cur, cfg, ns).0);
  191. cfg.blocks[block_no].instr[instr_no] = Instr::ExternalCall {
  192. success: *success,
  193. address,
  194. payload,
  195. args,
  196. value,
  197. gas,
  198. callty: callty.clone(),
  199. };
  200. }
  201. Instr::AbiDecode {
  202. res,
  203. selector,
  204. exception_block,
  205. tys,
  206. data,
  207. } => {
  208. let (data, _) = expression(data, Some(&vars), &cur, cfg, ns);
  209. cfg.blocks[block_no].instr[instr_no] = Instr::AbiDecode {
  210. res: res.clone(),
  211. selector: *selector,
  212. exception_block: *exception_block,
  213. tys: tys.clone(),
  214. data,
  215. }
  216. }
  217. Instr::AbiEncodeVector {
  218. res,
  219. tys,
  220. packed,
  221. selector,
  222. args,
  223. } => {
  224. let args = args
  225. .iter()
  226. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  227. .collect();
  228. let selector = selector
  229. .as_ref()
  230. .map(|expr| expression(expr, Some(&vars), &cur, cfg, ns).0);
  231. cfg.blocks[block_no].instr[instr_no] = Instr::AbiEncodeVector {
  232. res: *res,
  233. tys: tys.clone(),
  234. packed: *packed,
  235. selector,
  236. args,
  237. }
  238. }
  239. Instr::SelfDestruct { recipient } => {
  240. let (recipient, _) = expression(recipient, Some(&vars), &cur, cfg, ns);
  241. cfg.blocks[block_no].instr[instr_no] = Instr::SelfDestruct { recipient };
  242. }
  243. Instr::EmitEvent {
  244. event_no,
  245. data,
  246. data_tys,
  247. topics,
  248. topic_tys,
  249. } => {
  250. let data = data
  251. .iter()
  252. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  253. .collect();
  254. let topics = topics
  255. .iter()
  256. .map(|e| expression(e, Some(&vars), &cur, cfg, ns).0)
  257. .collect();
  258. cfg.blocks[block_no].instr[instr_no] = Instr::EmitEvent {
  259. event_no: *event_no,
  260. data,
  261. data_tys: data_tys.clone(),
  262. topics,
  263. topic_tys: topic_tys.clone(),
  264. }
  265. }
  266. _ => (),
  267. }
  268. reaching_definitions::apply_transfers(
  269. &cfg.blocks[block_no].transfers[instr_no],
  270. &mut vars,
  271. );
  272. }
  273. }
  274. }
  275. /// Recursively walk the expression and fold any constant expressions or variables. This function returns the
  276. /// constant folded expression, and a boolean which is true if the value is "pure", the value does not depend
  277. /// on context. This is used for constant folding, so that e.g. an external function call is not constant
  278. /// folded (and moved/copied as a result).
  279. fn expression(
  280. expr: &Expression,
  281. vars: Option<&reaching_definitions::VarDefs>,
  282. pos: &reaching_definitions::Def,
  283. cfg: &ControlFlowGraph,
  284. ns: &mut Namespace,
  285. ) -> (Expression, bool) {
  286. match expr {
  287. Expression::Add(loc, ty, left, right) => {
  288. let left = expression(left, vars, pos, cfg, ns);
  289. let right = expression(right, vars, pos, cfg, ns);
  290. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  291. (&left.0, &right.0)
  292. {
  293. bigint_to_expression(loc, ty, left.add(right))
  294. } else {
  295. (
  296. Expression::Add(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  297. left.1 && right.1,
  298. )
  299. }
  300. }
  301. Expression::Subtract(loc, ty, left, right) => {
  302. let left = expression(left, vars, pos, cfg, ns);
  303. let right = expression(right, vars, pos, cfg, ns);
  304. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  305. (&left.0, &right.0)
  306. {
  307. bigint_to_expression(loc, ty, left.sub(right))
  308. } else {
  309. (
  310. Expression::Subtract(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  311. left.1 && right.1,
  312. )
  313. }
  314. }
  315. Expression::Multiply(loc, ty, left, right) => {
  316. let left = expression(left, vars, pos, cfg, ns);
  317. let right = expression(right, vars, pos, cfg, ns);
  318. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  319. (&left.0, &right.0)
  320. {
  321. bigint_to_expression(loc, ty, left.mul(right))
  322. } else {
  323. (
  324. Expression::Multiply(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  325. left.1 && right.1,
  326. )
  327. }
  328. }
  329. Expression::BitwiseAnd(loc, ty, left, right) => {
  330. let left = expression(left, vars, pos, cfg, ns);
  331. let right = expression(right, vars, pos, cfg, ns);
  332. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  333. (&left.0, &right.0)
  334. {
  335. bigint_to_expression(loc, ty, left.bitand(right))
  336. } else {
  337. (
  338. Expression::BitwiseAnd(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  339. left.1 && right.1,
  340. )
  341. }
  342. }
  343. Expression::BitwiseOr(loc, ty, left, right) => {
  344. let left = expression(left, vars, pos, cfg, ns);
  345. let right = expression(right, vars, pos, cfg, ns);
  346. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  347. (&left.0, &right.0)
  348. {
  349. bigint_to_expression(loc, ty, left.bitor(right))
  350. } else {
  351. (
  352. Expression::BitwiseOr(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  353. left.1 && right.1,
  354. )
  355. }
  356. }
  357. Expression::BitwiseXor(loc, ty, left, right) => {
  358. let left = expression(left, vars, pos, cfg, ns);
  359. let right = expression(right, vars, pos, cfg, ns);
  360. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  361. (&left.0, &right.0)
  362. {
  363. bigint_to_expression(loc, ty, left.bitxor(right))
  364. } else {
  365. (
  366. Expression::BitwiseXor(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  367. left.1 && right.1,
  368. )
  369. }
  370. }
  371. Expression::ShiftLeft(loc, ty, left_expr, right_expr) => {
  372. let left = expression(left_expr, vars, pos, cfg, ns);
  373. let right = expression(right_expr, vars, pos, cfg, ns);
  374. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  375. (&left.0, &right.0)
  376. {
  377. if right.sign() == Sign::Minus || right >= &BigInt::from(left_expr.ty().bits(ns)) {
  378. ns.diagnostics.push(Diagnostic::error(
  379. *loc,
  380. format!("left shift by {} is not possible", right),
  381. ));
  382. } else {
  383. let right: u64 = right.to_u64().unwrap();
  384. return bigint_to_expression(loc, ty, left.shl(&right));
  385. }
  386. }
  387. (
  388. Expression::ShiftLeft(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  389. left.1 && right.1,
  390. )
  391. }
  392. Expression::ShiftRight(loc, ty, left_expr, right_expr, signed) => {
  393. let left = expression(left_expr, vars, pos, cfg, ns);
  394. let right = expression(right_expr, vars, pos, cfg, ns);
  395. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  396. (&left.0, &right.0)
  397. {
  398. if right.sign() == Sign::Minus || right >= &BigInt::from(left_expr.ty().bits(ns)) {
  399. ns.diagnostics.push(Diagnostic::error(
  400. *loc,
  401. format!("right shift by {} is not possible", right),
  402. ));
  403. } else {
  404. let right: u64 = right.to_u64().unwrap();
  405. return bigint_to_expression(loc, ty, left.shr(&right));
  406. }
  407. }
  408. (
  409. Expression::ShiftRight(
  410. *loc,
  411. ty.clone(),
  412. Box::new(left.0),
  413. Box::new(right.0),
  414. *signed,
  415. ),
  416. left.1 && right.1,
  417. )
  418. }
  419. Expression::Power(loc, ty, left, right) => {
  420. let left = expression(left, vars, pos, cfg, ns);
  421. let right = expression(right, vars, pos, cfg, ns);
  422. if let (Expression::NumberLiteral(_, _, left), Expression::NumberLiteral(_, _, right)) =
  423. (&left.0, &right.0)
  424. {
  425. if right.sign() == Sign::Minus || right >= &BigInt::from(u32::MAX) {
  426. ns.diagnostics.push(Diagnostic::error(
  427. *loc,
  428. format!("power {} not possible", right),
  429. ));
  430. } else {
  431. let right: u32 = right.to_u32().unwrap();
  432. return bigint_to_expression(loc, ty, left.pow(right));
  433. }
  434. }
  435. (
  436. Expression::Power(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  437. left.1 && right.1,
  438. )
  439. }
  440. Expression::Divide(loc, ty, left, right) => {
  441. let left = expression(left, vars, pos, cfg, ns);
  442. let right = expression(right, vars, pos, cfg, ns);
  443. if let Expression::NumberLiteral(_, _, right) = &right.0 {
  444. if right.is_zero() {
  445. ns.diagnostics
  446. .push(Diagnostic::error(*loc, String::from("divide by zero")));
  447. } else if let Expression::NumberLiteral(_, _, left) = &left.0 {
  448. return bigint_to_expression(loc, ty, left.div(right));
  449. }
  450. }
  451. (
  452. Expression::Divide(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  453. left.1 && right.1,
  454. )
  455. }
  456. Expression::Modulo(loc, ty, left, right) => {
  457. let left = expression(left, vars, pos, cfg, ns);
  458. let right = expression(right, vars, pos, cfg, ns);
  459. if let Expression::NumberLiteral(_, _, right) = &right.0 {
  460. if right.is_zero() {
  461. ns.diagnostics
  462. .push(Diagnostic::error(*loc, String::from("divide by zero")));
  463. } else if let Expression::NumberLiteral(_, _, left) = &left.0 {
  464. return bigint_to_expression(loc, ty, left.rem(right));
  465. }
  466. }
  467. (
  468. Expression::Modulo(*loc, ty.clone(), Box::new(left.0), Box::new(right.0)),
  469. left.1 && right.1,
  470. )
  471. }
  472. Expression::ZeroExt(loc, ty, expr) => {
  473. let expr = expression(expr, vars, pos, cfg, ns);
  474. if let Expression::NumberLiteral(_, _, n) = expr.0 {
  475. (Expression::NumberLiteral(*loc, ty.clone(), n), true)
  476. } else {
  477. (
  478. Expression::ZeroExt(*loc, ty.clone(), Box::new(expr.0)),
  479. expr.1,
  480. )
  481. }
  482. }
  483. Expression::SignExt(loc, ty, expr) => {
  484. let expr = expression(expr, vars, pos, cfg, ns);
  485. if let Expression::NumberLiteral(_, _, n) = expr.0 {
  486. (Expression::NumberLiteral(*loc, ty.clone(), n), true)
  487. } else {
  488. (
  489. Expression::SignExt(*loc, ty.clone(), Box::new(expr.0)),
  490. expr.1,
  491. )
  492. }
  493. }
  494. Expression::Trunc(loc, ty, expr) => {
  495. let expr = expression(expr, vars, pos, cfg, ns);
  496. if let Expression::NumberLiteral(_, _, n) = expr.0 {
  497. bigint_to_expression(loc, ty, n)
  498. } else {
  499. (
  500. Expression::Trunc(*loc, ty.clone(), Box::new(expr.0)),
  501. expr.1,
  502. )
  503. }
  504. }
  505. Expression::Complement(loc, ty, expr) => {
  506. let expr = expression(expr, vars, pos, cfg, ns);
  507. if let Expression::NumberLiteral(_, _, n) = expr.0 {
  508. bigint_to_expression(loc, ty, !n)
  509. } else {
  510. (
  511. Expression::Complement(*loc, ty.clone(), Box::new(expr.0)),
  512. expr.1,
  513. )
  514. }
  515. }
  516. Expression::UnaryMinus(loc, ty, expr) => {
  517. let expr = expression(expr, vars, pos, cfg, ns);
  518. if let Expression::NumberLiteral(_, _, n) = expr.0 {
  519. bigint_to_expression(loc, ty, -n)
  520. } else {
  521. (
  522. Expression::UnaryMinus(*loc, ty.clone(), Box::new(expr.0)),
  523. expr.1,
  524. )
  525. }
  526. }
  527. Expression::Variable(loc, ty, var) => {
  528. if !matches!(ty, Type::Ref(_) | Type::StorageRef(_)) {
  529. if let Some(vars) = vars {
  530. if let Some(defs) = vars.get(var) {
  531. // There must be at least one definition, and all should evaluate to the same value
  532. let mut v = None;
  533. for def in defs.keys() {
  534. if let Some(expr) = get_definition(def, cfg) {
  535. let expr = expression(expr, None, pos, cfg, ns);
  536. if expr.1 {
  537. if let Some(last) = &v {
  538. if !constants_equal(last, &expr.0) {
  539. v = None;
  540. break;
  541. }
  542. }
  543. v = Some(expr.0);
  544. } else {
  545. v = None;
  546. break;
  547. }
  548. } else {
  549. v = None;
  550. break;
  551. }
  552. }
  553. if let Some(expr) = v {
  554. if *loc != Loc(0, 0, 0) {
  555. ns.var_constants.insert(*loc, expr.clone());
  556. }
  557. return (expr, true);
  558. }
  559. }
  560. }
  561. }
  562. (expr.clone(), false)
  563. }
  564. Expression::Builtin(loc, tys, Builtin::Keccak256, args) => {
  565. let arg = expression(&args[0], vars, pos, cfg, ns);
  566. if let Expression::AllocDynamicArray(_, _, _, Some(bs)) = arg.0 {
  567. let mut hasher = Keccak::v256();
  568. hasher.update(&bs);
  569. let mut hash = [0u8; 32];
  570. hasher.finalize(&mut hash);
  571. (
  572. Expression::BytesLiteral(*loc, tys[0].clone(), hash.to_vec()),
  573. true,
  574. )
  575. } else {
  576. (
  577. Expression::Builtin(*loc, tys.clone(), Builtin::Keccak256, vec![arg.0]),
  578. false,
  579. )
  580. }
  581. }
  582. Expression::Builtin(loc, tys, Builtin::Ripemd160, args) => {
  583. let arg = expression(&args[0], vars, pos, cfg, ns);
  584. if let Expression::AllocDynamicArray(_, _, _, Some(bs)) = arg.0 {
  585. let mut hasher = Ripemd160::new();
  586. hasher.update(&bs);
  587. let result = hasher.finalize();
  588. (
  589. Expression::BytesLiteral(*loc, tys[0].clone(), result[..].to_vec()),
  590. true,
  591. )
  592. } else {
  593. (
  594. Expression::Builtin(*loc, tys.clone(), Builtin::Ripemd160, vec![arg.0]),
  595. false,
  596. )
  597. }
  598. }
  599. Expression::Builtin(loc, tys, Builtin::Blake2_256, args) => {
  600. let arg = expression(&args[0], vars, pos, cfg, ns);
  601. if let Expression::AllocDynamicArray(_, _, _, Some(bs)) = arg.0 {
  602. let hash = blake2_rfc::blake2b::blake2b(32, &[], &bs);
  603. (
  604. Expression::BytesLiteral(*loc, tys[0].clone(), hash.as_bytes().to_vec()),
  605. true,
  606. )
  607. } else {
  608. (
  609. Expression::Builtin(*loc, tys.clone(), Builtin::Blake2_256, vec![arg.0]),
  610. false,
  611. )
  612. }
  613. }
  614. Expression::Builtin(loc, tys, Builtin::Blake2_128, args) => {
  615. let arg = expression(&args[0], vars, pos, cfg, ns);
  616. if let Expression::AllocDynamicArray(_, _, _, Some(bs)) = arg.0 {
  617. let hash = blake2_rfc::blake2b::blake2b(16, &[], &bs);
  618. (
  619. Expression::BytesLiteral(*loc, tys[0].clone(), hash.as_bytes().to_vec()),
  620. true,
  621. )
  622. } else {
  623. (
  624. Expression::Builtin(*loc, tys.clone(), Builtin::Blake2_128, vec![arg.0]),
  625. false,
  626. )
  627. }
  628. }
  629. Expression::Builtin(loc, tys, Builtin::Sha256, args) => {
  630. let arg = expression(&args[0], vars, pos, cfg, ns);
  631. if let Expression::AllocDynamicArray(_, _, _, Some(bs)) = arg.0 {
  632. let mut hasher = Sha256::new();
  633. // write input message
  634. hasher.update(&bs);
  635. // read hash digest and consume hasher
  636. let result = hasher.finalize();
  637. (
  638. Expression::BytesLiteral(*loc, tys[0].clone(), result[..].to_vec()),
  639. true,
  640. )
  641. } else {
  642. (
  643. Expression::Builtin(*loc, tys.clone(), Builtin::Sha256, vec![arg.0]),
  644. false,
  645. )
  646. }
  647. }
  648. Expression::Keccak256(loc, ty, args) => {
  649. let mut all_constant = true;
  650. let mut hasher = Keccak::v256();
  651. let args = args
  652. .iter()
  653. .map(|expr| {
  654. let (expr, _) = expression(expr, vars, pos, cfg, ns);
  655. if all_constant {
  656. match &expr {
  657. Expression::AllocDynamicArray(_, _, _, Some(bs))
  658. | Expression::BytesLiteral(_, _, bs) => {
  659. hasher.update(&bs);
  660. }
  661. Expression::NumberLiteral(_, ty, n) => {
  662. let (sign, mut bs) = n.to_bytes_le();
  663. match ty {
  664. Type::Uint(bits) => bs.resize(*bits as usize / 8, 0),
  665. Type::Int(bits) => {
  666. let v = if sign == Sign::Minus { 0xffu8 } else { 0 };
  667. bs.resize(*bits as usize / 8, v);
  668. }
  669. Type::Bytes(n) => {
  670. while (*n as usize) < bs.len() {
  671. bs.insert(0, 0);
  672. }
  673. }
  674. _ => unreachable!(),
  675. }
  676. hasher.update(&bs);
  677. }
  678. _ => {
  679. all_constant = false;
  680. }
  681. }
  682. }
  683. expr
  684. })
  685. .collect();
  686. if all_constant {
  687. let mut hash = [0u8; 32];
  688. hasher.finalize(&mut hash);
  689. let mut hash = hash.to_vec();
  690. hash.reverse();
  691. (Expression::BytesLiteral(*loc, ty.clone(), hash), true)
  692. } else {
  693. (Expression::Keccak256(*loc, ty.clone(), args), false)
  694. }
  695. }
  696. // The rest is simply for recursing; no constant expansion should be done
  697. Expression::StructLiteral(loc, ty, args) => {
  698. let args = args
  699. .iter()
  700. .map(|expr| expression(expr, vars, pos, cfg, ns).0)
  701. .collect();
  702. (Expression::StructLiteral(*loc, ty.clone(), args), false)
  703. }
  704. Expression::ArrayLiteral(loc, ty, lengths, args) => {
  705. let args = args
  706. .iter()
  707. .map(|expr| expression(expr, vars, pos, cfg, ns).0)
  708. .collect();
  709. (
  710. Expression::ArrayLiteral(*loc, ty.clone(), lengths.clone(), args),
  711. false,
  712. )
  713. }
  714. Expression::ConstArrayLiteral(loc, ty, lengths, args) => {
  715. let args = args
  716. .iter()
  717. .map(|expr| expression(expr, vars, pos, cfg, ns).0)
  718. .collect();
  719. (
  720. Expression::ConstArrayLiteral(*loc, ty.clone(), lengths.clone(), args),
  721. false,
  722. )
  723. }
  724. Expression::Load(loc, ty, expr) => {
  725. let (expr, _) = expression(expr, vars, pos, cfg, ns);
  726. (Expression::Load(*loc, ty.clone(), Box::new(expr)), false)
  727. }
  728. Expression::StorageLoad(loc, ty, expr) => {
  729. let (expr, _) = expression(expr, vars, pos, cfg, ns);
  730. (
  731. Expression::StorageLoad(*loc, ty.clone(), Box::new(expr)),
  732. false,
  733. )
  734. }
  735. Expression::Cast(loc, ty, expr) => {
  736. let (expr, _) = expression(expr, vars, pos, cfg, ns);
  737. (Expression::Cast(*loc, ty.clone(), Box::new(expr)), false)
  738. }
  739. Expression::BytesCast(loc, from, to, expr) => {
  740. let (expr, _) = expression(expr, vars, pos, cfg, ns);
  741. (
  742. Expression::BytesCast(*loc, from.clone(), to.clone(), Box::new(expr)),
  743. false,
  744. )
  745. }
  746. Expression::More(loc, left, right) => {
  747. let left = expression(left, vars, pos, cfg, ns);
  748. let right = expression(right, vars, pos, cfg, ns);
  749. (
  750. Expression::More(*loc, Box::new(left.0), Box::new(right.0)),
  751. false,
  752. )
  753. }
  754. Expression::Less(loc, left, right) => {
  755. let left = expression(left, vars, pos, cfg, ns);
  756. let right = expression(right, vars, pos, cfg, ns);
  757. (
  758. Expression::Less(*loc, Box::new(left.0), Box::new(right.0)),
  759. false,
  760. )
  761. }
  762. Expression::MoreEqual(loc, left, right) => {
  763. let left = expression(left, vars, pos, cfg, ns);
  764. let right = expression(right, vars, pos, cfg, ns);
  765. (
  766. Expression::MoreEqual(*loc, Box::new(left.0), Box::new(right.0)),
  767. false,
  768. )
  769. }
  770. Expression::LessEqual(loc, left, right) => {
  771. let left = expression(left, vars, pos, cfg, ns);
  772. let right = expression(right, vars, pos, cfg, ns);
  773. (
  774. Expression::LessEqual(*loc, Box::new(left.0), Box::new(right.0)),
  775. false,
  776. )
  777. }
  778. Expression::Equal(loc, left, right) => {
  779. let left = expression(left, vars, pos, cfg, ns);
  780. let right = expression(right, vars, pos, cfg, ns);
  781. (
  782. Expression::Equal(*loc, Box::new(left.0), Box::new(right.0)),
  783. false,
  784. )
  785. }
  786. Expression::NotEqual(loc, left, right) => {
  787. let left = expression(left, vars, pos, cfg, ns);
  788. let right = expression(right, vars, pos, cfg, ns);
  789. (
  790. Expression::NotEqual(*loc, Box::new(left.0), Box::new(right.0)),
  791. false,
  792. )
  793. }
  794. Expression::Ternary(loc, ty, cond, left, right) => {
  795. let cond = expression(cond, vars, pos, cfg, ns);
  796. let left = expression(left, vars, pos, cfg, ns);
  797. let right = expression(right, vars, pos, cfg, ns);
  798. (
  799. Expression::Ternary(
  800. *loc,
  801. ty.clone(),
  802. Box::new(cond.0),
  803. Box::new(left.0),
  804. Box::new(right.0),
  805. ),
  806. false,
  807. )
  808. }
  809. Expression::Not(loc, expr) => {
  810. let expr = expression(expr, vars, pos, cfg, ns);
  811. (Expression::Not(*loc, Box::new(expr.0)), expr.1)
  812. }
  813. Expression::ArraySubscript(loc, ty, array, index) => {
  814. let array = expression(array, vars, pos, cfg, ns);
  815. let index = expression(index, vars, pos, cfg, ns);
  816. (
  817. Expression::ArraySubscript(*loc, ty.clone(), Box::new(array.0), Box::new(index.0)),
  818. false,
  819. )
  820. }
  821. Expression::StructMember(loc, ty, strct, member) => {
  822. let strct = expression(strct, vars, pos, cfg, ns);
  823. (
  824. Expression::StructMember(*loc, ty.clone(), Box::new(strct.0), *member),
  825. false,
  826. )
  827. }
  828. Expression::DynamicArrayLength(loc, array) => {
  829. let array = expression(array, vars, pos, cfg, ns);
  830. (
  831. Expression::DynamicArrayLength(*loc, Box::new(array.0)),
  832. false,
  833. )
  834. }
  835. Expression::DynamicArraySubscript(loc, ty, array, index) => {
  836. let array = expression(array, vars, pos, cfg, ns);
  837. let index = expression(index, vars, pos, cfg, ns);
  838. (
  839. Expression::DynamicArraySubscript(
  840. *loc,
  841. ty.clone(),
  842. Box::new(array.0),
  843. Box::new(index.0),
  844. ),
  845. false,
  846. )
  847. }
  848. Expression::StorageBytesSubscript(loc, array, index) => {
  849. let array = expression(array, vars, pos, cfg, ns);
  850. let index = expression(index, vars, pos, cfg, ns);
  851. (
  852. Expression::StorageBytesSubscript(*loc, Box::new(array.0), Box::new(index.0)),
  853. false,
  854. )
  855. }
  856. Expression::StorageArrayLength {
  857. loc,
  858. ty,
  859. array,
  860. elem_ty,
  861. } => {
  862. let array = expression(array, vars, pos, cfg, ns);
  863. (
  864. Expression::StorageArrayLength {
  865. loc: *loc,
  866. ty: ty.clone(),
  867. array: Box::new(array.0),
  868. elem_ty: elem_ty.clone(),
  869. },
  870. false,
  871. )
  872. }
  873. Expression::StringCompare(loc, left, right) => {
  874. if let (StringLocation::CompileTime(left), StringLocation::CompileTime(right)) =
  875. (left, right)
  876. {
  877. (Expression::BoolLiteral(*loc, left == right), true)
  878. } else {
  879. let left = if let StringLocation::RunTime(left) = left {
  880. StringLocation::RunTime(Box::new(expression(left, vars, pos, cfg, ns).0))
  881. } else {
  882. left.clone()
  883. };
  884. let right = if let StringLocation::RunTime(right) = right {
  885. StringLocation::RunTime(Box::new(expression(right, vars, pos, cfg, ns).0))
  886. } else {
  887. right.clone()
  888. };
  889. (Expression::StringCompare(*loc, left, right), false)
  890. }
  891. }
  892. Expression::StringConcat(loc, ty, left, right) => {
  893. if let (StringLocation::CompileTime(left), StringLocation::CompileTime(right)) =
  894. (left, right)
  895. {
  896. let mut bs = Vec::with_capacity(left.len() + right.len());
  897. bs.extend(left);
  898. bs.extend(right);
  899. (Expression::BytesLiteral(*loc, ty.clone(), bs), true)
  900. } else {
  901. let left = if let StringLocation::RunTime(left) = left {
  902. StringLocation::RunTime(Box::new(expression(left, vars, pos, cfg, ns).0))
  903. } else {
  904. left.clone()
  905. };
  906. let right = if let StringLocation::RunTime(right) = right {
  907. StringLocation::RunTime(Box::new(expression(right, vars, pos, cfg, ns).0))
  908. } else {
  909. right.clone()
  910. };
  911. (
  912. Expression::StringConcat(*loc, ty.clone(), left, right),
  913. false,
  914. )
  915. }
  916. }
  917. Expression::Builtin(loc, tys, builtin, args) => {
  918. let args = args
  919. .iter()
  920. .map(|expr| expression(expr, vars, pos, cfg, ns).0)
  921. .collect();
  922. (
  923. Expression::Builtin(*loc, tys.clone(), *builtin, args),
  924. false,
  925. )
  926. }
  927. Expression::ExternalFunction {
  928. loc,
  929. ty,
  930. address,
  931. function_no,
  932. } => {
  933. let address = expression(address, vars, pos, cfg, ns);
  934. (
  935. Expression::ExternalFunction {
  936. loc: *loc,
  937. ty: ty.clone(),
  938. address: Box::new(address.0),
  939. function_no: *function_no,
  940. },
  941. address.1,
  942. )
  943. }
  944. Expression::NumberLiteral(_, _, _)
  945. | Expression::BoolLiteral(_, _)
  946. | Expression::BytesLiteral(_, _, _)
  947. | Expression::CodeLiteral(_, _, _)
  948. | Expression::FunctionArg(_, _, _) => (expr.clone(), true),
  949. Expression::AllocDynamicArray(_, _, _, _)
  950. | Expression::ReturnData(_)
  951. | Expression::FormatString { .. }
  952. | Expression::InternalFunctionCfg(_) => (expr.clone(), false),
  953. // nothing else is permitted in cfg
  954. _ => unreachable!(),
  955. }
  956. }
  957. fn bigint_to_expression(loc: &Loc, ty: &Type, n: BigInt) -> (Expression, bool) {
  958. let n = match ty {
  959. Type::Uint(bits) => {
  960. if n.bits() > *bits as u64 {
  961. let (_, mut bs) = n.to_bytes_le();
  962. bs.truncate(*bits as usize / 8);
  963. BigInt::from_bytes_le(Sign::Plus, &bs)
  964. } else {
  965. n
  966. }
  967. }
  968. Type::Int(bits) => {
  969. if n.bits() > *bits as u64 {
  970. let mut bs = n.to_signed_bytes_le();
  971. bs.truncate(*bits as usize / 8);
  972. BigInt::from_signed_bytes_le(&bs)
  973. } else {
  974. n
  975. }
  976. }
  977. Type::StorageRef(_) => n,
  978. _ => unreachable!(),
  979. };
  980. (Expression::NumberLiteral(*loc, ty.clone(), n), true)
  981. }
  982. fn get_definition<'a>(
  983. def: &reaching_definitions::Def,
  984. cfg: &'a ControlFlowGraph,
  985. ) -> Option<&'a Expression> {
  986. if let Instr::Set { expr, .. } = &cfg.blocks[def.block_no].instr[def.instr_no] {
  987. Some(expr)
  988. } else {
  989. None
  990. }
  991. }
  992. /// Are these two expressions the same constant-folded value?
  993. fn constants_equal(left: &Expression, right: &Expression) -> bool {
  994. match left {
  995. Expression::NumberLiteral(_, _, left) => match right {
  996. Expression::NumberLiteral(_, _, right) => left == right,
  997. _ => false,
  998. },
  999. Expression::BytesLiteral(_, _, left)
  1000. | Expression::AllocDynamicArray(_, _, _, Some(left)) => match right {
  1001. Expression::BytesLiteral(_, _, right)
  1002. | Expression::AllocDynamicArray(_, _, _, Some(right)) => left == right,
  1003. _ => false,
  1004. },
  1005. _ => false,
  1006. }
  1007. }