expression.rs 73 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971
  1. // SPDX-License-Identifier: Apache-2.0
  2. use crate::codegen::cfg::{HashTy, ReturnCode};
  3. use crate::codegen::{Builtin, Expression};
  4. use crate::emit::binary::Binary;
  5. use crate::emit::math::{build_binary_op_with_overflow_check, multiply, power};
  6. use crate::emit::strings::{format_string, string_location};
  7. use crate::emit::{BinaryOp, TargetRuntime, Variable};
  8. use crate::sema::ast::{Namespace, RetrieveType, StructType, Type};
  9. use crate::Target;
  10. use inkwell::module::Linkage;
  11. use inkwell::types::{BasicType, StringRadix};
  12. use inkwell::values::{ArrayValue, BasicValueEnum, FunctionValue, IntValue};
  13. use inkwell::{AddressSpace, IntPredicate};
  14. use num_bigint::Sign;
  15. use std::collections::HashMap;
  16. /// The expression function recursively emits code for expressions. The BasicEnumValue it
  17. /// returns depends on the context; if it is simple integer, bool or bytes32 expression, the value
  18. /// is an Intvalue. For references to arrays, it is a PointerValue to the array. For references
  19. /// to storage, it is the storage slot. The references types are dereferenced by the Expression::Load()
  20. /// and Expression::StorageLoad() expression types.
  21. pub(super) fn expression<'a, T: TargetRuntime<'a> + ?Sized>(
  22. target: &T,
  23. bin: &Binary<'a>,
  24. e: &Expression,
  25. vartab: &HashMap<usize, Variable<'a>>,
  26. function: FunctionValue<'a>,
  27. ns: &Namespace,
  28. ) -> BasicValueEnum<'a> {
  29. match e {
  30. Expression::FunctionArg(_, _, pos) => function.get_nth_param(*pos as u32).unwrap(),
  31. Expression::BoolLiteral(_, val) => {
  32. bin.context.bool_type().const_int(*val as u64, false).into()
  33. }
  34. Expression::NumberLiteral(_, Type::Address(_), val) => {
  35. // address can be negative; "address(-1)" is 0xffff...
  36. let mut bs = val.to_signed_bytes_be();
  37. // make sure it's no more than 32
  38. if bs.len() > ns.address_length {
  39. // remove leading bytes
  40. for _ in 0..bs.len() - ns.address_length {
  41. bs.remove(0);
  42. }
  43. } else {
  44. // insert leading bytes
  45. let val = if val.sign() == Sign::Minus { 0xff } else { 0 };
  46. for _ in 0..ns.address_length - bs.len() {
  47. bs.insert(0, val);
  48. }
  49. }
  50. let address = bs
  51. .iter()
  52. .map(|b| bin.context.i8_type().const_int(*b as u64, false))
  53. .collect::<Vec<IntValue>>();
  54. bin.context.i8_type().const_array(&address).into()
  55. }
  56. Expression::NumberLiteral(_, ty, n) => bin.number_literal(ty.bits(ns) as u32, n, ns).into(),
  57. Expression::StructLiteral(_, ty, exprs) => {
  58. let struct_ty = bin.llvm_type(ty, ns);
  59. let s = bin
  60. .builder
  61. .build_call(
  62. bin.module.get_function("__malloc").unwrap(),
  63. &[struct_ty
  64. .size_of()
  65. .unwrap()
  66. .const_cast(bin.context.i32_type(), false)
  67. .into()],
  68. "",
  69. )
  70. .try_as_basic_value()
  71. .left()
  72. .unwrap()
  73. .into_pointer_value();
  74. let s = bin.builder.build_pointer_cast(
  75. s,
  76. struct_ty.ptr_type(AddressSpace::default()),
  77. "struct_literal",
  78. );
  79. for (i, expr) in exprs.iter().enumerate() {
  80. let elemptr = unsafe {
  81. bin.builder.build_gep(
  82. s,
  83. &[
  84. bin.context.i32_type().const_zero(),
  85. bin.context.i32_type().const_int(i as u64, false),
  86. ],
  87. "struct member",
  88. )
  89. };
  90. let elem = expression(target, bin, expr, vartab, function, ns);
  91. let elem = if expr.ty().is_fixed_reference_type() {
  92. bin.builder.build_load(elem.into_pointer_value(), "elem")
  93. } else {
  94. elem
  95. };
  96. bin.builder.build_store(elemptr, elem);
  97. }
  98. s.into()
  99. }
  100. Expression::BytesLiteral(_, _, bs) => {
  101. let ty = bin.context.custom_width_int_type((bs.len() * 8) as u32);
  102. // hex"11223344" should become i32 0x11223344
  103. let s = hex::encode(bs);
  104. ty.const_int_from_string(&s, StringRadix::Hexadecimal)
  105. .unwrap()
  106. .into()
  107. }
  108. Expression::Add(loc, _, unchecked, l, r) => {
  109. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  110. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  111. if bin.options.math_overflow_check && !*unchecked {
  112. let signed = l.ty().is_signed_int();
  113. build_binary_op_with_overflow_check(
  114. target,
  115. bin,
  116. function,
  117. left,
  118. right,
  119. BinaryOp::Add,
  120. signed,
  121. ns,
  122. *loc,
  123. )
  124. .into()
  125. } else {
  126. bin.builder.build_int_add(left, right, "").into()
  127. }
  128. }
  129. Expression::Subtract(loc, _, unchecked, l, r) => {
  130. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  131. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  132. if bin.options.math_overflow_check && !*unchecked {
  133. let signed = l.ty().is_signed_int();
  134. build_binary_op_with_overflow_check(
  135. target,
  136. bin,
  137. function,
  138. left,
  139. right,
  140. BinaryOp::Subtract,
  141. signed,
  142. ns,
  143. *loc,
  144. )
  145. .into()
  146. } else {
  147. bin.builder.build_int_sub(left, right, "").into()
  148. }
  149. }
  150. Expression::Multiply(loc, res_ty, unchecked, l, r) => {
  151. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  152. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  153. multiply(
  154. target,
  155. bin,
  156. function,
  157. *unchecked,
  158. left,
  159. right,
  160. res_ty.is_signed_int(),
  161. ns,
  162. *loc,
  163. )
  164. .into()
  165. }
  166. Expression::UnsignedDivide(loc, _, l, r) => {
  167. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  168. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  169. let bits = left.get_type().get_bit_width();
  170. if bits > 64 {
  171. let div_bits = if bits <= 128 { 128 } else { 256 };
  172. let name = format!("udivmod{div_bits}");
  173. let f = bin
  174. .module
  175. .get_function(&name)
  176. .expect("div function missing");
  177. let ty = bin.context.custom_width_int_type(div_bits);
  178. let dividend = bin.build_alloca(function, ty, "dividend");
  179. let divisor = bin.build_alloca(function, ty, "divisor");
  180. let rem = bin.build_alloca(function, ty, "remainder");
  181. let quotient = bin.build_alloca(function, ty, "quotient");
  182. bin.builder.build_store(
  183. dividend,
  184. if bits < div_bits {
  185. bin.builder.build_int_z_extend(left, ty, "")
  186. } else {
  187. left
  188. },
  189. );
  190. bin.builder.build_store(
  191. divisor,
  192. if bits < div_bits {
  193. bin.builder.build_int_z_extend(right, ty, "")
  194. } else {
  195. right
  196. },
  197. );
  198. let ret = bin
  199. .builder
  200. .build_call(
  201. f,
  202. &[dividend.into(), divisor.into(), rem.into(), quotient.into()],
  203. "udiv",
  204. )
  205. .try_as_basic_value()
  206. .left()
  207. .unwrap();
  208. let success = bin.builder.build_int_compare(
  209. IntPredicate::EQ,
  210. ret.into_int_value(),
  211. bin.context.i32_type().const_zero(),
  212. "success",
  213. );
  214. let success_block = bin.context.append_basic_block(function, "success");
  215. let bail_block = bin.context.append_basic_block(function, "bail");
  216. bin.builder
  217. .build_conditional_branch(success, success_block, bail_block);
  218. bin.builder.position_at_end(bail_block);
  219. // throw division by zero error should be an assert
  220. target.log_runtime_error(bin, "division by zero".to_string(), Some(*loc), ns);
  221. target.assert_failure(
  222. bin,
  223. bin.context
  224. .i8_type()
  225. .ptr_type(AddressSpace::default())
  226. .const_null(),
  227. bin.context.i32_type().const_zero(),
  228. );
  229. bin.builder.position_at_end(success_block);
  230. let quotient = bin
  231. .builder
  232. .build_load(quotient, "quotient")
  233. .into_int_value();
  234. if bits < div_bits {
  235. bin.builder
  236. .build_int_truncate(quotient, left.get_type(), "")
  237. } else {
  238. quotient
  239. }
  240. .into()
  241. } else {
  242. bin.builder.build_int_unsigned_div(left, right, "").into()
  243. }
  244. }
  245. Expression::SignedDivide(loc, _, l, r) => {
  246. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  247. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  248. let bits = left.get_type().get_bit_width();
  249. if bits > 64 {
  250. let div_bits = if bits <= 128 { 128 } else { 256 };
  251. let name = format!("sdivmod{div_bits}");
  252. let f = bin
  253. .module
  254. .get_function(&name)
  255. .expect("div function missing");
  256. let ty = bin.context.custom_width_int_type(div_bits);
  257. let dividend = bin.build_alloca(function, ty, "dividend");
  258. let divisor = bin.build_alloca(function, ty, "divisor");
  259. let rem = bin.build_alloca(function, ty, "remainder");
  260. let quotient = bin.build_alloca(function, ty, "quotient");
  261. bin.builder.build_store(
  262. dividend,
  263. if bits < div_bits {
  264. bin.builder.build_int_s_extend(left, ty, "")
  265. } else {
  266. left
  267. },
  268. );
  269. bin.builder.build_store(
  270. divisor,
  271. if bits < div_bits {
  272. bin.builder.build_int_s_extend(right, ty, "")
  273. } else {
  274. right
  275. },
  276. );
  277. let ret = bin
  278. .builder
  279. .build_call(
  280. f,
  281. &[dividend.into(), divisor.into(), rem.into(), quotient.into()],
  282. "udiv",
  283. )
  284. .try_as_basic_value()
  285. .left()
  286. .unwrap();
  287. let success = bin.builder.build_int_compare(
  288. IntPredicate::EQ,
  289. ret.into_int_value(),
  290. bin.context.i32_type().const_zero(),
  291. "success",
  292. );
  293. let success_block = bin.context.append_basic_block(function, "success");
  294. let bail_block = bin.context.append_basic_block(function, "bail");
  295. bin.builder
  296. .build_conditional_branch(success, success_block, bail_block);
  297. bin.builder.position_at_end(bail_block);
  298. // throw division by zero error should be an assert
  299. target.log_runtime_error(bin, "division by zero".to_string(), Some(*loc), ns);
  300. target.assert_failure(
  301. bin,
  302. bin.context
  303. .i8_type()
  304. .ptr_type(AddressSpace::default())
  305. .const_null(),
  306. bin.context.i32_type().const_zero(),
  307. );
  308. bin.builder.position_at_end(success_block);
  309. let quotient = bin
  310. .builder
  311. .build_load(quotient, "quotient")
  312. .into_int_value();
  313. if bits < div_bits {
  314. bin.builder
  315. .build_int_truncate(quotient, left.get_type(), "")
  316. } else {
  317. quotient
  318. }
  319. .into()
  320. } else if ns.target == Target::Solana {
  321. // no signed div on BPF; do abs udev and then negate if needed
  322. let left_negative = bin.builder.build_int_compare(
  323. IntPredicate::SLT,
  324. left,
  325. left.get_type().const_zero(),
  326. "left_negative",
  327. );
  328. let left = bin
  329. .builder
  330. .build_select(
  331. left_negative,
  332. bin.builder.build_int_neg(left, "signed_left"),
  333. left,
  334. "left_abs",
  335. )
  336. .into_int_value();
  337. let right_negative = bin.builder.build_int_compare(
  338. IntPredicate::SLT,
  339. right,
  340. right.get_type().const_zero(),
  341. "right_negative",
  342. );
  343. let right = bin
  344. .builder
  345. .build_select(
  346. right_negative,
  347. bin.builder.build_int_neg(right, "signed_right"),
  348. right,
  349. "right_abs",
  350. )
  351. .into_int_value();
  352. let res = bin.builder.build_int_unsigned_div(left, right, "");
  353. let negate_result =
  354. bin.builder
  355. .build_xor(left_negative, right_negative, "negate_result");
  356. bin.builder.build_select(
  357. negate_result,
  358. bin.builder.build_int_neg(res, "unsigned_res"),
  359. res,
  360. "res",
  361. )
  362. } else {
  363. bin.builder.build_int_signed_div(left, right, "").into()
  364. }
  365. }
  366. Expression::UnsignedModulo(loc, _, l, r) => {
  367. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  368. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  369. let bits = left.get_type().get_bit_width();
  370. if bits > 64 {
  371. let div_bits = if bits <= 128 { 128 } else { 256 };
  372. let name = format!("udivmod{div_bits}");
  373. let f = bin
  374. .module
  375. .get_function(&name)
  376. .expect("div function missing");
  377. let ty = bin.context.custom_width_int_type(div_bits);
  378. let dividend = bin.build_alloca(function, ty, "dividend");
  379. let divisor = bin.build_alloca(function, ty, "divisor");
  380. let rem = bin.build_alloca(function, ty, "remainder");
  381. let quotient = bin.build_alloca(function, ty, "quotient");
  382. bin.builder.build_store(
  383. dividend,
  384. if bits < div_bits {
  385. bin.builder.build_int_z_extend(left, ty, "")
  386. } else {
  387. left
  388. },
  389. );
  390. bin.builder.build_store(
  391. divisor,
  392. if bits < div_bits {
  393. bin.builder.build_int_z_extend(right, ty, "")
  394. } else {
  395. right
  396. },
  397. );
  398. let ret = bin
  399. .builder
  400. .build_call(
  401. f,
  402. &[dividend.into(), divisor.into(), rem.into(), quotient.into()],
  403. "udiv",
  404. )
  405. .try_as_basic_value()
  406. .left()
  407. .unwrap();
  408. let success = bin.builder.build_int_compare(
  409. IntPredicate::EQ,
  410. ret.into_int_value(),
  411. bin.context.i32_type().const_zero(),
  412. "success",
  413. );
  414. let success_block = bin.context.append_basic_block(function, "success");
  415. let bail_block = bin.context.append_basic_block(function, "bail");
  416. bin.builder
  417. .build_conditional_branch(success, success_block, bail_block);
  418. bin.builder.position_at_end(bail_block);
  419. // throw division by zero error should be an assert
  420. target.log_runtime_error(bin, "division by zero".to_string(), Some(*loc), ns);
  421. target.assert_failure(
  422. bin,
  423. bin.context
  424. .i8_type()
  425. .ptr_type(AddressSpace::default())
  426. .const_null(),
  427. bin.context.i32_type().const_zero(),
  428. );
  429. bin.builder.position_at_end(success_block);
  430. let rem = bin.builder.build_load(rem, "urem").into_int_value();
  431. if bits < div_bits {
  432. bin.builder
  433. .build_int_truncate(rem, bin.context.custom_width_int_type(bits), "")
  434. } else {
  435. rem
  436. }
  437. .into()
  438. } else {
  439. bin.builder.build_int_unsigned_rem(left, right, "").into()
  440. }
  441. }
  442. Expression::SignedModulo(loc, _, l, r) => {
  443. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  444. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  445. let bits = left.get_type().get_bit_width();
  446. if bits > 64 {
  447. let div_bits = if bits <= 128 { 128 } else { 256 };
  448. let name = format!("sdivmod{div_bits}");
  449. let f = bin
  450. .module
  451. .get_function(&name)
  452. .expect("div function missing");
  453. let ty = bin.context.custom_width_int_type(div_bits);
  454. let dividend = bin.build_alloca(function, ty, "dividend");
  455. let divisor = bin.build_alloca(function, ty, "divisor");
  456. let rem = bin.build_alloca(function, ty, "remainder");
  457. let quotient = bin.build_alloca(function, ty, "quotient");
  458. bin.builder.build_store(
  459. dividend,
  460. if bits < div_bits {
  461. bin.builder.build_int_s_extend(left, ty, "")
  462. } else {
  463. left
  464. },
  465. );
  466. bin.builder.build_store(
  467. divisor,
  468. if bits < div_bits {
  469. bin.builder.build_int_s_extend(right, ty, "")
  470. } else {
  471. right
  472. },
  473. );
  474. let ret = bin
  475. .builder
  476. .build_call(
  477. f,
  478. &[dividend.into(), divisor.into(), rem.into(), quotient.into()],
  479. "sdiv",
  480. )
  481. .try_as_basic_value()
  482. .left()
  483. .unwrap();
  484. let success = bin.builder.build_int_compare(
  485. IntPredicate::EQ,
  486. ret.into_int_value(),
  487. bin.context.i32_type().const_zero(),
  488. "success",
  489. );
  490. let success_block = bin.context.append_basic_block(function, "success");
  491. let bail_block = bin.context.append_basic_block(function, "bail");
  492. bin.builder
  493. .build_conditional_branch(success, success_block, bail_block);
  494. bin.builder.position_at_end(bail_block);
  495. // throw division by zero error should be an assert
  496. target.log_runtime_error(bin, "division by zero".to_string(), Some(*loc), ns);
  497. target.assert_failure(
  498. bin,
  499. bin.context
  500. .i8_type()
  501. .ptr_type(AddressSpace::default())
  502. .const_null(),
  503. bin.context.i32_type().const_zero(),
  504. );
  505. bin.builder.position_at_end(success_block);
  506. let rem = bin.builder.build_load(rem, "srem").into_int_value();
  507. if bits < div_bits {
  508. bin.builder
  509. .build_int_truncate(rem, bin.context.custom_width_int_type(bits), "")
  510. } else {
  511. rem
  512. }
  513. .into()
  514. } else if ns.target == Target::Solana {
  515. // no signed rem on BPF; do abs udev and then negate if needed
  516. let left_negative = bin.builder.build_int_compare(
  517. IntPredicate::SLT,
  518. left,
  519. left.get_type().const_zero(),
  520. "left_negative",
  521. );
  522. let left = bin.builder.build_select(
  523. left_negative,
  524. bin.builder.build_int_neg(left, "signed_left"),
  525. left,
  526. "left_abs",
  527. );
  528. let right_negative = bin.builder.build_int_compare(
  529. IntPredicate::SLT,
  530. right,
  531. right.get_type().const_zero(),
  532. "right_negative",
  533. );
  534. let right = bin.builder.build_select(
  535. right_negative,
  536. bin.builder.build_int_neg(right, "signed_right"),
  537. right,
  538. "right_abs",
  539. );
  540. let res = bin.builder.build_int_unsigned_rem(
  541. left.into_int_value(),
  542. right.into_int_value(),
  543. "",
  544. );
  545. bin.builder.build_select(
  546. left_negative,
  547. bin.builder.build_int_neg(res, "unsigned_res"),
  548. res,
  549. "res",
  550. )
  551. } else {
  552. bin.builder.build_int_signed_rem(left, right, "").into()
  553. }
  554. }
  555. Expression::Power(loc, res_ty, unchecked, l, r) => {
  556. let left = expression(target, bin, l, vartab, function, ns);
  557. let right = expression(target, bin, r, vartab, function, ns);
  558. let bits = left.into_int_value().get_type().get_bit_width();
  559. let o = bin.build_alloca(function, left.get_type(), "");
  560. let f = power(
  561. target,
  562. bin,
  563. *unchecked,
  564. bits,
  565. res_ty.is_signed_int(),
  566. o,
  567. ns,
  568. *loc,
  569. );
  570. // If the function returns zero, then the operation was successful.
  571. let error_return = bin
  572. .builder
  573. .build_call(f, &[left.into(), right.into(), o.into()], "power")
  574. .try_as_basic_value()
  575. .left()
  576. .unwrap();
  577. // Load the result pointer
  578. let res = bin.builder.build_load(o, "");
  579. if !bin.options.math_overflow_check || *unchecked || ns.target != Target::Solana {
  580. // In Substrate, overflow case will hit an unreachable expression, so no additional checks are needed.
  581. res
  582. } else {
  583. // In Solana, a return other than zero will abort execution. We need to check if power() returned a zero or not.
  584. let error_block = bin.context.append_basic_block(function, "error");
  585. let return_block = bin.context.append_basic_block(function, "return_block");
  586. let error_ret = bin.builder.build_int_compare(
  587. IntPredicate::NE,
  588. error_return.into_int_value(),
  589. error_return.get_type().const_zero().into_int_value(),
  590. "",
  591. );
  592. bin.builder
  593. .build_conditional_branch(error_ret, error_block, return_block);
  594. bin.builder.position_at_end(error_block);
  595. target.log_runtime_error(bin, "math overflow".to_string(), Some(*loc), ns);
  596. target.assert_failure(
  597. bin,
  598. bin.context
  599. .i8_type()
  600. .ptr_type(AddressSpace::default())
  601. .const_null(),
  602. bin.context.i32_type().const_zero(),
  603. );
  604. bin.builder.position_at_end(return_block);
  605. res
  606. }
  607. }
  608. Expression::Equal(_, l, r) => {
  609. if l.ty().is_address() {
  610. let mut res = bin.context.bool_type().const_int(1, false);
  611. let left = expression(target, bin, l, vartab, function, ns).into_array_value();
  612. let right = expression(target, bin, r, vartab, function, ns).into_array_value();
  613. // TODO: Address should be passed around as pointer. Once this is done, we can replace
  614. // this with a call to address_equal()
  615. for index in 0..ns.address_length {
  616. let l = bin
  617. .builder
  618. .build_extract_value(left, index as u32, "left")
  619. .unwrap()
  620. .into_int_value();
  621. let r = bin
  622. .builder
  623. .build_extract_value(right, index as u32, "right")
  624. .unwrap()
  625. .into_int_value();
  626. res = bin.builder.build_and(
  627. res,
  628. bin.builder.build_int_compare(IntPredicate::EQ, l, r, ""),
  629. "cmp",
  630. );
  631. }
  632. res.into()
  633. } else {
  634. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  635. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  636. bin.builder
  637. .build_int_compare(IntPredicate::EQ, left, right, "")
  638. .into()
  639. }
  640. }
  641. Expression::NotEqual(_, l, r) => {
  642. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  643. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  644. bin.builder
  645. .build_int_compare(IntPredicate::NE, left, right, "")
  646. .into()
  647. }
  648. Expression::SignedMore(_, l, r) | Expression::UnsignedMore(_, l, r) => {
  649. if l.ty().is_address() {
  650. compare_address(target, bin, l, r, IntPredicate::SGT, vartab, function, ns).into()
  651. } else {
  652. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  653. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  654. bin.builder
  655. .build_int_compare(
  656. if matches!(e, Expression::SignedMore(..)) {
  657. IntPredicate::SGT
  658. } else {
  659. IntPredicate::UGT
  660. },
  661. left,
  662. right,
  663. "",
  664. )
  665. .into()
  666. }
  667. }
  668. Expression::MoreEqual(_, l, r) => {
  669. if l.ty().is_address() {
  670. compare_address(target, bin, l, r, IntPredicate::SGE, vartab, function, ns).into()
  671. } else {
  672. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  673. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  674. bin.builder
  675. .build_int_compare(
  676. if l.ty().is_signed_int() {
  677. IntPredicate::SGE
  678. } else {
  679. IntPredicate::UGE
  680. },
  681. left,
  682. right,
  683. "",
  684. )
  685. .into()
  686. }
  687. }
  688. Expression::SignedLess(_, l, r) | Expression::UnsignedLess(_, l, r) => {
  689. if l.ty().is_address() {
  690. compare_address(target, bin, l, r, IntPredicate::SLT, vartab, function, ns).into()
  691. } else {
  692. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  693. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  694. bin.builder
  695. .build_int_compare(
  696. if matches!(e, Expression::SignedLess(..)) {
  697. IntPredicate::SLT
  698. } else {
  699. IntPredicate::ULT
  700. },
  701. left,
  702. right,
  703. "",
  704. )
  705. .into()
  706. }
  707. }
  708. Expression::LessEqual(_, l, r) => {
  709. if l.ty().is_address() {
  710. compare_address(target, bin, l, r, IntPredicate::SLE, vartab, function, ns).into()
  711. } else {
  712. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  713. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  714. bin.builder
  715. .build_int_compare(
  716. if l.ty().is_signed_int() {
  717. IntPredicate::SLE
  718. } else {
  719. IntPredicate::ULE
  720. },
  721. left,
  722. right,
  723. "",
  724. )
  725. .into()
  726. }
  727. }
  728. Expression::Variable(_, _, s) => vartab[s].value,
  729. Expression::GetRef(_, _, expr) => {
  730. let address = expression(target, bin, expr, vartab, function, ns).into_array_value();
  731. let stack = bin.build_alloca(function, address.get_type(), "address");
  732. bin.builder.build_store(stack, address);
  733. stack.into()
  734. }
  735. Expression::Load(_, ty, e) => {
  736. let ptr = expression(target, bin, e, vartab, function, ns).into_pointer_value();
  737. let value = bin.builder.build_load(ptr, "");
  738. if ty.is_reference_type(ns) && !ty.is_fixed_reference_type() {
  739. // if the pointer is null, it needs to be allocated
  740. let allocation_needed = bin
  741. .builder
  742. .build_is_null(value.into_pointer_value(), "allocation_needed");
  743. let allocate = bin.context.append_basic_block(function, "allocate");
  744. let already_allocated = bin
  745. .context
  746. .append_basic_block(function, "already_allocated");
  747. bin.builder.build_conditional_branch(
  748. allocation_needed,
  749. allocate,
  750. already_allocated,
  751. );
  752. let entry = bin.builder.get_insert_block().unwrap();
  753. bin.builder.position_at_end(allocate);
  754. // allocate a new struct
  755. let ty = e.ty();
  756. let llvm_ty = bin.llvm_type(ty.deref_memory(), ns);
  757. let new_struct = bin
  758. .builder
  759. .build_call(
  760. bin.module.get_function("__malloc").unwrap(),
  761. &[llvm_ty
  762. .size_of()
  763. .unwrap()
  764. .const_cast(bin.context.i32_type(), false)
  765. .into()],
  766. "",
  767. )
  768. .try_as_basic_value()
  769. .left()
  770. .unwrap()
  771. .into_pointer_value();
  772. let new_struct = bin.builder.build_pointer_cast(
  773. new_struct,
  774. llvm_ty.ptr_type(AddressSpace::default()),
  775. &format!("new_{}", ty.to_string(ns)),
  776. );
  777. bin.builder.build_store(ptr, new_struct);
  778. bin.builder.build_unconditional_branch(already_allocated);
  779. bin.builder.position_at_end(already_allocated);
  780. // insert phi node
  781. let combined_struct_ptr = bin.builder.build_phi(
  782. llvm_ty.ptr_type(AddressSpace::default()),
  783. &format!("ptr_{}", ty.to_string(ns)),
  784. );
  785. combined_struct_ptr.add_incoming(&[(&value, entry), (&new_struct, allocate)]);
  786. combined_struct_ptr.as_basic_value()
  787. } else {
  788. value
  789. }
  790. }
  791. Expression::ZeroExt(_, t, e) => {
  792. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  793. let ty = bin.llvm_type(t, ns);
  794. bin.builder
  795. .build_int_z_extend(e, ty.into_int_type(), "")
  796. .into()
  797. }
  798. Expression::UnaryMinus(_, _, e) => {
  799. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  800. bin.builder.build_int_neg(e, "").into()
  801. }
  802. Expression::SignExt(_, t, e) => {
  803. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  804. let ty = bin.llvm_type(t, ns);
  805. bin.builder
  806. .build_int_s_extend(e, ty.into_int_type(), "")
  807. .into()
  808. }
  809. Expression::Trunc(_, t, e) => {
  810. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  811. let ty = bin.llvm_type(t, ns);
  812. bin.builder
  813. .build_int_truncate(e, ty.into_int_type(), "")
  814. .into()
  815. }
  816. Expression::Cast(_, to, e) => {
  817. let from = e.ty();
  818. let e = expression(target, bin, e, vartab, function, ns);
  819. runtime_cast(bin, function, &from, to, e, ns)
  820. }
  821. Expression::BytesCast(_, Type::DynamicBytes, Type::Bytes(_), e) => {
  822. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  823. let size = e.get_type().get_bit_width() / 8;
  824. let size = bin.context.i32_type().const_int(size as u64, false);
  825. let elem_size = bin.context.i32_type().const_int(1, false);
  826. // Swap the byte order
  827. let bytes_ptr = bin.build_alloca(function, e.get_type(), "bytes_ptr");
  828. bin.builder.build_store(bytes_ptr, e);
  829. let bytes_ptr = bin.builder.build_pointer_cast(
  830. bytes_ptr,
  831. bin.context.i8_type().ptr_type(AddressSpace::default()),
  832. "bytes_ptr",
  833. );
  834. let init = bin.builder.build_pointer_cast(
  835. bin.build_alloca(function, e.get_type(), "init"),
  836. bin.context.i8_type().ptr_type(AddressSpace::default()),
  837. "init",
  838. );
  839. bin.builder.build_call(
  840. bin.module.get_function("__leNtobeN").unwrap(),
  841. &[bytes_ptr.into(), init.into(), size.into()],
  842. "",
  843. );
  844. bin.builder
  845. .build_call(
  846. bin.module.get_function("vector_new").unwrap(),
  847. &[size.into(), elem_size.into(), init.into()],
  848. "",
  849. )
  850. .try_as_basic_value()
  851. .left()
  852. .unwrap()
  853. }
  854. Expression::BytesCast(loc, Type::Bytes(n), Type::DynamicBytes, e) => {
  855. let array = expression(target, bin, e, vartab, function, ns);
  856. let len = bin.vector_len(array);
  857. // Check if equal to n
  858. let is_equal_to_n = bin.builder.build_int_compare(
  859. IntPredicate::EQ,
  860. len,
  861. bin.context.i32_type().const_int(*n as u64, false),
  862. "is_equal_to_n",
  863. );
  864. let cast = bin.context.append_basic_block(function, "cast");
  865. let error = bin.context.append_basic_block(function, "error");
  866. bin.builder
  867. .build_conditional_branch(is_equal_to_n, cast, error);
  868. bin.builder.position_at_end(error);
  869. target.log_runtime_error(bin, "bytes cast error".to_string(), Some(*loc), ns);
  870. target.assert_failure(
  871. bin,
  872. bin.context
  873. .i8_type()
  874. .ptr_type(AddressSpace::default())
  875. .const_null(),
  876. bin.context.i32_type().const_zero(),
  877. );
  878. bin.builder.position_at_end(cast);
  879. let bytes_ptr = bin.vector_bytes(array);
  880. // Switch byte order
  881. let ty = bin.context.custom_width_int_type(*n as u32 * 8);
  882. let le_bytes_ptr = bin.build_alloca(function, ty, "le_bytes");
  883. bin.builder.build_call(
  884. bin.module.get_function("__beNtoleN").unwrap(),
  885. &[
  886. bytes_ptr.into(),
  887. bin.builder
  888. .build_pointer_cast(
  889. le_bytes_ptr,
  890. bin.context.i8_type().ptr_type(AddressSpace::default()),
  891. "le_bytes_ptr",
  892. )
  893. .into(),
  894. len.into(),
  895. ],
  896. "",
  897. );
  898. bin.builder.build_load(le_bytes_ptr, "bytes")
  899. }
  900. Expression::Not(_, e) => {
  901. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  902. bin.builder
  903. .build_int_compare(IntPredicate::EQ, e, e.get_type().const_zero(), "")
  904. .into()
  905. }
  906. Expression::Complement(_, _, e) => {
  907. let e = expression(target, bin, e, vartab, function, ns).into_int_value();
  908. bin.builder.build_not(e, "").into()
  909. }
  910. Expression::BitwiseOr(_, _, l, r) => {
  911. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  912. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  913. bin.builder.build_or(left, right, "").into()
  914. }
  915. Expression::BitwiseAnd(_, _, l, r) => {
  916. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  917. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  918. bin.builder.build_and(left, right, "").into()
  919. }
  920. Expression::BitwiseXor(_, _, l, r) => {
  921. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  922. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  923. bin.builder.build_xor(left, right, "").into()
  924. }
  925. Expression::ShiftLeft(_, _, l, r) => {
  926. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  927. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  928. bin.builder.build_left_shift(left, right, "").into()
  929. }
  930. Expression::ShiftRight(_, _, l, r, signed) => {
  931. let left = expression(target, bin, l, vartab, function, ns).into_int_value();
  932. let right = expression(target, bin, r, vartab, function, ns).into_int_value();
  933. bin.builder
  934. .build_right_shift(left, right, *signed, "")
  935. .into()
  936. }
  937. Expression::Subscript(loc, elem_ty, ty, a, i) => {
  938. if ty.is_storage_bytes() {
  939. let index = expression(target, bin, i, vartab, function, ns).into_int_value();
  940. let slot = expression(target, bin, a, vartab, function, ns).into_int_value();
  941. target
  942. .get_storage_bytes_subscript(bin, function, slot, index, *loc, ns)
  943. .into()
  944. } else if ty.is_contract_storage() {
  945. let array = expression(target, bin, a, vartab, function, ns).into_int_value();
  946. let index = expression(target, bin, i, vartab, function, ns);
  947. target
  948. .storage_subscript(bin, function, ty, array, index, ns)
  949. .into()
  950. } else if elem_ty.is_builtin_struct() == Some(StructType::AccountInfo) {
  951. let array = expression(target, bin, a, vartab, function, ns).into_pointer_value();
  952. let index = expression(target, bin, i, vartab, function, ns).into_int_value();
  953. unsafe {
  954. bin.builder
  955. .build_gep(array, &[index], "account_info")
  956. .into()
  957. }
  958. } else if ty.is_dynamic_memory() {
  959. let array = expression(target, bin, a, vartab, function, ns);
  960. let ty = bin.llvm_field_ty(elem_ty, ns);
  961. let mut array_index =
  962. expression(target, bin, i, vartab, function, ns).into_int_value();
  963. // bounds checking already done; we can down-cast if necessary
  964. if array_index.get_type().get_bit_width() > 32 {
  965. array_index = bin.builder.build_int_truncate(
  966. array_index,
  967. bin.context.i32_type(),
  968. "index",
  969. );
  970. }
  971. let index = bin.builder.build_int_mul(
  972. array_index,
  973. ty.into_pointer_type()
  974. .get_element_type()
  975. .size_of()
  976. .unwrap()
  977. .const_cast(bin.context.i32_type(), false),
  978. "",
  979. );
  980. let elem = unsafe {
  981. bin.builder
  982. .build_gep(bin.vector_bytes(array), &[index], "index_access")
  983. };
  984. bin.builder
  985. .build_pointer_cast(elem, ty.into_pointer_type(), "elem")
  986. .into()
  987. } else {
  988. let array = expression(target, bin, a, vartab, function, ns).into_pointer_value();
  989. let index = expression(target, bin, i, vartab, function, ns).into_int_value();
  990. unsafe {
  991. bin.builder
  992. .build_gep(
  993. array,
  994. &[bin.context.i32_type().const_zero(), index],
  995. "index_access",
  996. )
  997. .into()
  998. }
  999. }
  1000. }
  1001. Expression::StructMember(_, _, a, _)
  1002. if a.ty().is_builtin_struct() == Some(StructType::AccountInfo) =>
  1003. {
  1004. target.builtin(bin, e, vartab, function, ns)
  1005. }
  1006. Expression::StructMember(_, _, a, i) => {
  1007. let struct_ptr = expression(target, bin, a, vartab, function, ns).into_pointer_value();
  1008. bin.builder
  1009. .build_struct_gep(struct_ptr, *i as u32, "struct member")
  1010. .unwrap()
  1011. .into()
  1012. }
  1013. Expression::ConstArrayLiteral(_, _, dims, exprs) => {
  1014. // For const arrays (declared with "constant" keyword, we should create a global constant
  1015. let mut dims = dims.iter();
  1016. let exprs = exprs
  1017. .iter()
  1018. .map(|e| expression(target, bin, e, vartab, function, ns).into_int_value())
  1019. .collect::<Vec<IntValue>>();
  1020. let ty = exprs[0].get_type();
  1021. let top_size = *dims.next().unwrap();
  1022. // Create a vector of ArrayValues
  1023. let mut arrays = exprs
  1024. .chunks(top_size as usize)
  1025. .map(|a| ty.const_array(a))
  1026. .collect::<Vec<ArrayValue>>();
  1027. let mut ty = ty.array_type(top_size);
  1028. // for each dimension, split the array into futher arrays
  1029. for d in dims {
  1030. ty = ty.array_type(*d);
  1031. arrays = arrays
  1032. .chunks(*d as usize)
  1033. .map(|a| ty.const_array(a))
  1034. .collect::<Vec<ArrayValue>>();
  1035. }
  1036. // We actually end up with an array with a single entry
  1037. // now we've created the type, and the const array. Put it into a global
  1038. let gv =
  1039. bin.module
  1040. .add_global(ty, Some(AddressSpace::default()), "const_array_literal");
  1041. gv.set_linkage(Linkage::Internal);
  1042. gv.set_initializer(&arrays[0]);
  1043. gv.set_constant(true);
  1044. gv.as_pointer_value().into()
  1045. }
  1046. Expression::ArrayLiteral(_, ty, dims, exprs) => {
  1047. // non-const array literals should alloca'ed and each element assigned
  1048. let ty = bin.llvm_type(ty, ns);
  1049. let p = bin
  1050. .builder
  1051. .build_call(
  1052. bin.module.get_function("__malloc").unwrap(),
  1053. &[ty.size_of()
  1054. .unwrap()
  1055. .const_cast(bin.context.i32_type(), false)
  1056. .into()],
  1057. "array_literal",
  1058. )
  1059. .try_as_basic_value()
  1060. .left()
  1061. .unwrap();
  1062. let array = bin.builder.build_pointer_cast(
  1063. p.into_pointer_value(),
  1064. ty.ptr_type(AddressSpace::default()),
  1065. "array_literal",
  1066. );
  1067. for (i, expr) in exprs.iter().enumerate() {
  1068. let mut ind = vec![bin.context.i32_type().const_zero()];
  1069. let mut e = i as u32;
  1070. for d in dims {
  1071. ind.insert(1, bin.context.i32_type().const_int((e % *d).into(), false));
  1072. e /= *d;
  1073. }
  1074. let elemptr = unsafe { bin.builder.build_gep(array, &ind, &format!("elemptr{i}")) };
  1075. let elem = expression(target, bin, expr, vartab, function, ns);
  1076. let elem = if expr.ty().is_fixed_reference_type() {
  1077. bin.builder.build_load(elem.into_pointer_value(), "elem")
  1078. } else {
  1079. elem
  1080. };
  1081. bin.builder.build_store(elemptr, elem);
  1082. }
  1083. array.into()
  1084. }
  1085. Expression::AllocDynamicBytes(_, ty, size, init) => {
  1086. if matches!(ty, Type::Slice(_)) {
  1087. let init = init.as_ref().unwrap();
  1088. let data = bin.emit_global_string("const_string", init, true);
  1089. bin.llvm_type(ty, ns)
  1090. .into_struct_type()
  1091. .const_named_struct(&[
  1092. data.into(),
  1093. bin.context
  1094. .custom_width_int_type(ns.target.ptr_size().into())
  1095. .const_int(init.len() as u64, false)
  1096. .into(),
  1097. ])
  1098. .into()
  1099. } else {
  1100. let elem = match ty {
  1101. Type::Slice(_) | Type::String | Type::DynamicBytes => Type::Bytes(1),
  1102. _ => ty.array_elem(),
  1103. };
  1104. let size = expression(target, bin, size, vartab, function, ns).into_int_value();
  1105. let elem_size = bin
  1106. .llvm_type(&elem, ns)
  1107. .size_of()
  1108. .unwrap()
  1109. .const_cast(bin.context.i32_type(), false);
  1110. bin.vector_new(size, elem_size, init.as_ref()).into()
  1111. }
  1112. }
  1113. Expression::Builtin(_, _, Builtin::ArrayLength, args)
  1114. if args[0].ty().array_deref().is_builtin_struct().is_none() =>
  1115. {
  1116. let array = expression(target, bin, &args[0], vartab, function, ns);
  1117. bin.vector_len(array).into()
  1118. }
  1119. Expression::Builtin(_, returns, Builtin::ReadFromBuffer, args) => {
  1120. let v = expression(target, bin, &args[0], vartab, function, ns);
  1121. let offset = expression(target, bin, &args[1], vartab, function, ns).into_int_value();
  1122. let data = if args[0].ty().is_dynamic_memory() {
  1123. bin.vector_bytes(v)
  1124. } else {
  1125. v.into_pointer_value()
  1126. };
  1127. let start = unsafe { bin.builder.build_gep(data, &[offset], "start") };
  1128. if matches!(returns[0], Type::Bytes(_) | Type::FunctionSelector) {
  1129. let n = returns[0].bytes(ns);
  1130. let store = bin.build_alloca(
  1131. function,
  1132. bin.context.custom_width_int_type(n as u32 * 8),
  1133. "stack",
  1134. );
  1135. bin.builder.build_call(
  1136. bin.module.get_function("__beNtoleN").unwrap(),
  1137. &[
  1138. bin.builder
  1139. .build_pointer_cast(
  1140. start,
  1141. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1142. "",
  1143. )
  1144. .into(),
  1145. bin.builder
  1146. .build_pointer_cast(
  1147. store,
  1148. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1149. "",
  1150. )
  1151. .into(),
  1152. bin.context.i32_type().const_int(n as u64, false).into(),
  1153. ],
  1154. "",
  1155. );
  1156. bin.builder.build_load(store, &format!("bytes{n}"))
  1157. } else {
  1158. let start = bin.builder.build_pointer_cast(
  1159. start,
  1160. bin.llvm_type(&returns[0], ns)
  1161. .ptr_type(AddressSpace::default()),
  1162. "start",
  1163. );
  1164. bin.builder.build_load(start, "value")
  1165. }
  1166. }
  1167. Expression::Keccak256(_, _, exprs) => {
  1168. let mut length = bin.context.i32_type().const_zero();
  1169. let mut values: Vec<(BasicValueEnum, IntValue, Type)> = Vec::new();
  1170. // first we need to calculate the length of the buffer and get the types/lengths
  1171. for e in exprs {
  1172. let v = expression(target, bin, e, vartab, function, ns);
  1173. let len = match e.ty() {
  1174. Type::DynamicBytes | Type::String => bin.vector_len(v),
  1175. _ => v
  1176. .get_type()
  1177. .size_of()
  1178. .unwrap()
  1179. .const_cast(bin.context.i32_type(), false),
  1180. };
  1181. length = bin.builder.build_int_add(length, len, "");
  1182. values.push((v, len, e.ty()));
  1183. }
  1184. // now allocate a buffer
  1185. let src = bin
  1186. .builder
  1187. .build_array_alloca(bin.context.i8_type(), length, "keccak_src");
  1188. // fill in all the fields
  1189. let mut offset = bin.context.i32_type().const_zero();
  1190. for (v, len, ty) in values {
  1191. let elem = unsafe { bin.builder.build_gep(src, &[offset], "elem") };
  1192. offset = bin.builder.build_int_add(offset, len, "");
  1193. match ty {
  1194. Type::DynamicBytes | Type::String => {
  1195. let data = bin.vector_bytes(v);
  1196. bin.builder.build_call(
  1197. bin.module.get_function("__memcpy").unwrap(),
  1198. &[
  1199. elem.into(),
  1200. bin.builder
  1201. .build_pointer_cast(
  1202. data,
  1203. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1204. "data",
  1205. )
  1206. .into(),
  1207. len.into(),
  1208. ],
  1209. "",
  1210. );
  1211. }
  1212. _ => {
  1213. let elem = bin.builder.build_pointer_cast(
  1214. elem,
  1215. v.get_type().ptr_type(AddressSpace::default()),
  1216. "",
  1217. );
  1218. bin.builder.build_store(elem, v);
  1219. }
  1220. }
  1221. }
  1222. let dst = bin
  1223. .builder
  1224. .build_alloca(bin.context.custom_width_int_type(256), "keccak_dst");
  1225. target.keccak256_hash(bin, src, length, dst, ns);
  1226. bin.builder.build_load(dst, "keccak256_hash")
  1227. }
  1228. Expression::StringCompare(_, l, r) => {
  1229. let (left, left_len) = string_location(target, bin, l, vartab, function, ns);
  1230. let (right, right_len) = string_location(target, bin, r, vartab, function, ns);
  1231. bin.builder
  1232. .build_call(
  1233. bin.module.get_function("__memcmp").unwrap(),
  1234. &[left.into(), left_len.into(), right.into(), right_len.into()],
  1235. "",
  1236. )
  1237. .try_as_basic_value()
  1238. .left()
  1239. .unwrap()
  1240. }
  1241. Expression::StringConcat(_, _, l, r) => {
  1242. let (left, left_len) = string_location(target, bin, l, vartab, function, ns);
  1243. let (right, right_len) = string_location(target, bin, r, vartab, function, ns);
  1244. bin.builder
  1245. .build_call(
  1246. bin.module.get_function("concat").unwrap(),
  1247. &[left.into(), left_len.into(), right.into(), right_len.into()],
  1248. "",
  1249. )
  1250. .try_as_basic_value()
  1251. .left()
  1252. .unwrap()
  1253. }
  1254. Expression::ReturnData(_) => target.return_data(bin, function).into(),
  1255. Expression::StorageArrayLength { array, elem_ty, .. } => {
  1256. let slot = expression(target, bin, array, vartab, function, ns).into_int_value();
  1257. target
  1258. .storage_array_length(bin, function, slot, elem_ty, ns)
  1259. .into()
  1260. }
  1261. Expression::AbiEncode {
  1262. tys, packed, args, ..
  1263. } => target
  1264. .abi_encode_to_vector(
  1265. bin,
  1266. function,
  1267. &packed
  1268. .iter()
  1269. .map(|a| expression(target, bin, a, vartab, function, ns))
  1270. .collect::<Vec<BasicValueEnum>>(),
  1271. &args
  1272. .iter()
  1273. .map(|a| expression(target, bin, a, vartab, function, ns))
  1274. .collect::<Vec<BasicValueEnum>>(),
  1275. tys,
  1276. ns,
  1277. )
  1278. .into(),
  1279. Expression::Builtin(_, _, Builtin::Signature, _) if ns.target != Target::Solana => {
  1280. // need to byte-reverse selector
  1281. let selector = bin.build_alloca(function, bin.context.i32_type(), "selector");
  1282. // byte order needs to be reversed. e.g. hex"11223344" should be 0x10 0x11 0x22 0x33 0x44
  1283. bin.builder.build_call(
  1284. bin.module.get_function("__beNtoleN").unwrap(),
  1285. &[
  1286. bin.builder
  1287. .build_pointer_cast(
  1288. bin.selector.as_pointer_value(),
  1289. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1290. "",
  1291. )
  1292. .into(),
  1293. bin.builder
  1294. .build_pointer_cast(
  1295. selector,
  1296. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1297. "",
  1298. )
  1299. .into(),
  1300. bin.context.i32_type().const_int(4, false).into(),
  1301. ],
  1302. "",
  1303. );
  1304. bin.builder.build_load(selector, "selector")
  1305. }
  1306. Expression::Builtin(_, _, Builtin::AddMod, args) => {
  1307. let arith_ty = bin.context.custom_width_int_type(512);
  1308. let res_ty = bin.context.custom_width_int_type(256);
  1309. let x = expression(target, bin, &args[0], vartab, function, ns).into_int_value();
  1310. let y = expression(target, bin, &args[1], vartab, function, ns).into_int_value();
  1311. let k = expression(target, bin, &args[2], vartab, function, ns).into_int_value();
  1312. let dividend = bin.builder.build_int_add(
  1313. bin.builder.build_int_z_extend(x, arith_ty, "wide_x"),
  1314. bin.builder.build_int_z_extend(y, arith_ty, "wide_y"),
  1315. "x_plus_y",
  1316. );
  1317. let divisor = bin.builder.build_int_z_extend(k, arith_ty, "wide_k");
  1318. let pdividend = bin.build_alloca(function, arith_ty, "dividend");
  1319. let pdivisor = bin.build_alloca(function, arith_ty, "divisor");
  1320. let rem = bin.build_alloca(function, arith_ty, "remainder");
  1321. let quotient = bin.build_alloca(function, arith_ty, "quotient");
  1322. bin.builder.build_store(pdividend, dividend);
  1323. bin.builder.build_store(pdivisor, divisor);
  1324. let ret = bin
  1325. .builder
  1326. .build_call(
  1327. bin.module.get_function("udivmod512").unwrap(),
  1328. &[
  1329. pdividend.into(),
  1330. pdivisor.into(),
  1331. rem.into(),
  1332. quotient.into(),
  1333. ],
  1334. "quotient",
  1335. )
  1336. .try_as_basic_value()
  1337. .left()
  1338. .unwrap()
  1339. .into_int_value();
  1340. let success = bin.builder.build_int_compare(
  1341. IntPredicate::EQ,
  1342. ret,
  1343. bin.context.i32_type().const_zero(),
  1344. "success",
  1345. );
  1346. let success_block = bin.context.append_basic_block(function, "success");
  1347. let bail_block = bin.context.append_basic_block(function, "bail");
  1348. bin.builder
  1349. .build_conditional_branch(success, success_block, bail_block);
  1350. bin.builder.position_at_end(bail_block);
  1351. // On Solana the return type is 64 bit
  1352. let ret: BasicValueEnum = bin
  1353. .builder
  1354. .build_int_z_extend(
  1355. ret,
  1356. bin.return_values[&ReturnCode::Success].get_type(),
  1357. "ret",
  1358. )
  1359. .into();
  1360. bin.builder.build_return(Some(&ret));
  1361. bin.builder.position_at_end(success_block);
  1362. let remainder = bin.builder.build_load(rem, "remainder").into_int_value();
  1363. bin.builder
  1364. .build_int_truncate(remainder, res_ty, "quotient")
  1365. .into()
  1366. }
  1367. Expression::Builtin(_, _, Builtin::MulMod, args) => {
  1368. let arith_ty = bin.context.custom_width_int_type(512);
  1369. let res_ty = bin.context.custom_width_int_type(256);
  1370. let x = expression(target, bin, &args[0], vartab, function, ns).into_int_value();
  1371. let y = expression(target, bin, &args[1], vartab, function, ns).into_int_value();
  1372. let x_m = bin.build_alloca(function, arith_ty, "x_m");
  1373. let y_m = bin.build_alloca(function, arith_ty, "x_y");
  1374. let x_times_y_m = bin.build_alloca(function, arith_ty, "x_times_y_m");
  1375. bin.builder
  1376. .build_store(x_m, bin.builder.build_int_z_extend(x, arith_ty, "wide_x"));
  1377. bin.builder
  1378. .build_store(y_m, bin.builder.build_int_z_extend(y, arith_ty, "wide_y"));
  1379. bin.builder.build_call(
  1380. bin.module.get_function("__mul32").unwrap(),
  1381. &[
  1382. bin.builder
  1383. .build_pointer_cast(
  1384. x_m,
  1385. bin.context.i32_type().ptr_type(AddressSpace::default()),
  1386. "left",
  1387. )
  1388. .into(),
  1389. bin.builder
  1390. .build_pointer_cast(
  1391. y_m,
  1392. bin.context.i32_type().ptr_type(AddressSpace::default()),
  1393. "right",
  1394. )
  1395. .into(),
  1396. bin.builder
  1397. .build_pointer_cast(
  1398. x_times_y_m,
  1399. bin.context.i32_type().ptr_type(AddressSpace::default()),
  1400. "output",
  1401. )
  1402. .into(),
  1403. bin.context.i32_type().const_int(512 / 32, false).into(),
  1404. ],
  1405. "",
  1406. );
  1407. let k = expression(target, bin, &args[2], vartab, function, ns).into_int_value();
  1408. let dividend = bin.builder.build_load(x_times_y_m, "x_t_y");
  1409. let divisor = bin.builder.build_int_z_extend(k, arith_ty, "wide_k");
  1410. let pdividend = bin.build_alloca(function, arith_ty, "dividend");
  1411. let pdivisor = bin.build_alloca(function, arith_ty, "divisor");
  1412. let rem = bin.build_alloca(function, arith_ty, "remainder");
  1413. let quotient = bin.build_alloca(function, arith_ty, "quotient");
  1414. bin.builder.build_store(pdividend, dividend);
  1415. bin.builder.build_store(pdivisor, divisor);
  1416. let ret = bin
  1417. .builder
  1418. .build_call(
  1419. bin.module.get_function("udivmod512").unwrap(),
  1420. &[
  1421. pdividend.into(),
  1422. pdivisor.into(),
  1423. rem.into(),
  1424. quotient.into(),
  1425. ],
  1426. "quotient",
  1427. )
  1428. .try_as_basic_value()
  1429. .left()
  1430. .unwrap()
  1431. .into_int_value();
  1432. let success = bin.builder.build_int_compare(
  1433. IntPredicate::EQ,
  1434. ret,
  1435. bin.context.i32_type().const_zero(),
  1436. "success",
  1437. );
  1438. let success_block = bin.context.append_basic_block(function, "success");
  1439. let bail_block = bin.context.append_basic_block(function, "bail");
  1440. bin.builder
  1441. .build_conditional_branch(success, success_block, bail_block);
  1442. bin.builder.position_at_end(bail_block);
  1443. // On Solana the return type is 64 bit
  1444. let ret: BasicValueEnum = bin
  1445. .builder
  1446. .build_int_z_extend(
  1447. ret,
  1448. bin.return_values[&ReturnCode::Success].get_type(),
  1449. "ret",
  1450. )
  1451. .into();
  1452. bin.builder.build_return(Some(&ret));
  1453. bin.builder.position_at_end(success_block);
  1454. let remainder = bin.builder.build_load(rem, "quotient").into_int_value();
  1455. bin.builder
  1456. .build_int_truncate(remainder, res_ty, "quotient")
  1457. .into()
  1458. }
  1459. Expression::Builtin(_, _, hash @ Builtin::Ripemd160, args)
  1460. | Expression::Builtin(_, _, hash @ Builtin::Keccak256, args)
  1461. | Expression::Builtin(_, _, hash @ Builtin::Blake2_128, args)
  1462. | Expression::Builtin(_, _, hash @ Builtin::Blake2_256, args)
  1463. | Expression::Builtin(_, _, hash @ Builtin::Sha256, args) => {
  1464. let v = expression(target, bin, &args[0], vartab, function, ns);
  1465. let hash = match hash {
  1466. Builtin::Ripemd160 => HashTy::Ripemd160,
  1467. Builtin::Sha256 => HashTy::Sha256,
  1468. Builtin::Keccak256 => HashTy::Keccak256,
  1469. Builtin::Blake2_128 => HashTy::Blake2_128,
  1470. Builtin::Blake2_256 => HashTy::Blake2_256,
  1471. _ => unreachable!(),
  1472. };
  1473. target
  1474. .hash(
  1475. bin,
  1476. function,
  1477. hash,
  1478. bin.vector_bytes(v),
  1479. bin.vector_len(v),
  1480. ns,
  1481. )
  1482. .into()
  1483. }
  1484. Expression::Builtin(..) => target.builtin(bin, e, vartab, function, ns),
  1485. Expression::InternalFunctionCfg(cfg_no) => bin.functions[cfg_no]
  1486. .as_global_value()
  1487. .as_pointer_value()
  1488. .into(),
  1489. Expression::FormatString(_, args) => format_string(target, bin, args, vartab, function, ns),
  1490. Expression::AdvancePointer {
  1491. pointer,
  1492. bytes_offset,
  1493. } => {
  1494. let pointer = if pointer.ty().is_dynamic_memory() {
  1495. bin.vector_bytes(expression(target, bin, pointer, vartab, function, ns))
  1496. } else {
  1497. expression(target, bin, pointer, vartab, function, ns).into_pointer_value()
  1498. };
  1499. let offset =
  1500. expression(target, bin, bytes_offset, vartab, function, ns).into_int_value();
  1501. let advanced = unsafe { bin.builder.build_gep(pointer, &[offset], "adv_pointer") };
  1502. advanced.into()
  1503. }
  1504. Expression::RationalNumberLiteral(..)
  1505. | Expression::List(..)
  1506. | Expression::Undefined(..)
  1507. | Expression::Poison
  1508. | Expression::BytesCast(..) => {
  1509. unreachable!("should not exist in cfg")
  1510. }
  1511. }
  1512. }
  1513. pub(super) fn compare_address<'a, T: TargetRuntime<'a> + ?Sized>(
  1514. target: &T,
  1515. binary: &Binary<'a>,
  1516. left: &Expression,
  1517. right: &Expression,
  1518. op: inkwell::IntPredicate,
  1519. vartab: &HashMap<usize, Variable<'a>>,
  1520. function: FunctionValue<'a>,
  1521. ns: &Namespace,
  1522. ) -> IntValue<'a> {
  1523. let l = expression(target, binary, left, vartab, function, ns).into_array_value();
  1524. let r = expression(target, binary, right, vartab, function, ns).into_array_value();
  1525. let left = binary.build_alloca(function, binary.address_type(ns), "left");
  1526. let right = binary.build_alloca(function, binary.address_type(ns), "right");
  1527. binary.builder.build_store(left, l);
  1528. binary.builder.build_store(right, r);
  1529. let res = binary
  1530. .builder
  1531. .build_call(
  1532. binary.module.get_function("__memcmp_ord").unwrap(),
  1533. &[
  1534. binary
  1535. .builder
  1536. .build_pointer_cast(
  1537. left,
  1538. binary.context.i8_type().ptr_type(AddressSpace::default()),
  1539. "left",
  1540. )
  1541. .into(),
  1542. binary
  1543. .builder
  1544. .build_pointer_cast(
  1545. right,
  1546. binary.context.i8_type().ptr_type(AddressSpace::default()),
  1547. "right",
  1548. )
  1549. .into(),
  1550. binary
  1551. .context
  1552. .i32_type()
  1553. .const_int(ns.address_length as u64, false)
  1554. .into(),
  1555. ],
  1556. "",
  1557. )
  1558. .try_as_basic_value()
  1559. .left()
  1560. .unwrap()
  1561. .into_int_value();
  1562. binary
  1563. .builder
  1564. .build_int_compare(op, res, binary.context.i32_type().const_zero(), "")
  1565. }
  1566. fn runtime_cast<'a>(
  1567. bin: &Binary<'a>,
  1568. function: FunctionValue<'a>,
  1569. from: &Type,
  1570. to: &Type,
  1571. val: BasicValueEnum<'a>,
  1572. ns: &Namespace,
  1573. ) -> BasicValueEnum<'a> {
  1574. if matches!(from, Type::Address(_) | Type::Contract(_))
  1575. && matches!(to, Type::Address(_) | Type::Contract(_))
  1576. {
  1577. // no conversion needed
  1578. val
  1579. } else if let Type::Address(_) = to {
  1580. let llvm_ty = bin.llvm_type(from, ns);
  1581. let src = bin.build_alloca(function, llvm_ty, "dest");
  1582. bin.builder.build_store(src, val.into_int_value());
  1583. let dest = bin.build_alloca(function, bin.address_type(ns), "address");
  1584. let len = bin
  1585. .context
  1586. .i32_type()
  1587. .const_int(ns.address_length as u64, false);
  1588. bin.builder.build_call(
  1589. bin.module.get_function("__leNtobeN").unwrap(),
  1590. &[
  1591. bin.builder
  1592. .build_pointer_cast(
  1593. src,
  1594. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1595. "address_ptr",
  1596. )
  1597. .into(),
  1598. bin.builder
  1599. .build_pointer_cast(
  1600. dest,
  1601. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1602. "dest_ptr",
  1603. )
  1604. .into(),
  1605. len.into(),
  1606. ],
  1607. "",
  1608. );
  1609. bin.builder.build_load(dest, "val")
  1610. } else if let Type::Address(_) = from {
  1611. let llvm_ty = bin.llvm_type(to, ns);
  1612. let src = bin.build_alloca(function, bin.address_type(ns), "address");
  1613. bin.builder.build_store(src, val.into_array_value());
  1614. let dest = bin.build_alloca(function, llvm_ty, "dest");
  1615. let len = bin
  1616. .context
  1617. .i32_type()
  1618. .const_int(ns.address_length as u64, false);
  1619. bin.builder.build_call(
  1620. bin.module.get_function("__beNtoleN").unwrap(),
  1621. &[
  1622. bin.builder
  1623. .build_pointer_cast(
  1624. src,
  1625. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1626. "address_ptr",
  1627. )
  1628. .into(),
  1629. bin.builder
  1630. .build_pointer_cast(
  1631. dest,
  1632. bin.context.i8_type().ptr_type(AddressSpace::default()),
  1633. "dest_ptr",
  1634. )
  1635. .into(),
  1636. len.into(),
  1637. ],
  1638. "",
  1639. );
  1640. bin.builder.build_load(dest, "val")
  1641. } else if matches!(from, Type::Bool) && matches!(to, Type::Int(_) | Type::Uint(_)) {
  1642. bin.builder
  1643. .build_int_cast(
  1644. val.into_int_value(),
  1645. bin.llvm_type(to, ns).into_int_type(),
  1646. "bool_to_int_cast",
  1647. )
  1648. .into()
  1649. } else if !from.is_contract_storage()
  1650. && from.is_reference_type(ns)
  1651. && matches!(to, Type::Uint(_))
  1652. {
  1653. bin.builder
  1654. .build_ptr_to_int(
  1655. val.into_pointer_value(),
  1656. bin.llvm_type(to, ns).into_int_type(),
  1657. "ptr_to_int",
  1658. )
  1659. .into()
  1660. } else if to.is_reference_type(ns) && matches!(from, Type::Uint(_)) {
  1661. bin.builder
  1662. .build_int_to_ptr(
  1663. val.into_int_value(),
  1664. bin.llvm_type(to, ns).ptr_type(AddressSpace::default()),
  1665. "int_to_ptr",
  1666. )
  1667. .into()
  1668. } else if matches!((from, to), (Type::DynamicBytes, Type::Slice(_))) {
  1669. let slice = bin.build_alloca(function, bin.llvm_type(to, ns), "slice");
  1670. let data = bin.vector_bytes(val);
  1671. let data_ptr = bin.builder.build_struct_gep(slice, 0, "data").unwrap();
  1672. bin.builder.build_store(data_ptr, data);
  1673. let len =
  1674. bin.builder
  1675. .build_int_z_extend(bin.vector_len(val), bin.context.i64_type(), "len");
  1676. let len_ptr = bin.builder.build_struct_gep(slice, 1, "len").unwrap();
  1677. bin.builder.build_store(len_ptr, len);
  1678. bin.builder.build_load(slice, "slice")
  1679. } else {
  1680. val
  1681. }
  1682. }
  1683. pub(crate) fn string_to_basic_value<'a>(
  1684. bin: &Binary<'a>,
  1685. ns: &Namespace,
  1686. input: String,
  1687. ) -> BasicValueEnum<'a> {
  1688. let elem = Type::Bytes(1);
  1689. let size = bin.context.i32_type().const_int(input.len() as u64, false);
  1690. let elem_size = bin
  1691. .llvm_type(&elem, ns)
  1692. .size_of()
  1693. .unwrap()
  1694. .const_cast(bin.context.i32_type(), false);
  1695. let init = Option::Some(input.as_bytes().to_vec());
  1696. bin.vector_new(size, elem_size, init.as_ref()).into()
  1697. }