scale.sol 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // RUN: --target polkadot --emit cfg
  2. contract ExternalFunctions {
  3. function(int32) external returns (uint64) func;
  4. // BEGIN-CHECK: ExternalFunctions::ExternalFunctions::function::to_storage
  5. function to_storage() public {
  6. // CHECK: ty:function(int32) external returns (uint64) %temp.4 = function(int32) external returns (uint64)(function(int32) external returns (uint64)(struct { hex"42761137", (load (builtin GetAddress ())) }))
  7. // CHECK: store storage slot(uint256 0) ty:function(int32) external returns (uint64) = %temp.4
  8. func = this.foo;
  9. }
  10. function foo(int32) public returns (uint64) {
  11. return 0xabbaabba;
  12. }
  13. function bar(function(int32) external returns (uint64) f) public {
  14. assert(f(102) == 0xabbaabba);
  15. // CHECK: ty:function(int32) external returns (uint64) %f = (arg #0)
  16. // CHECK: ty:bytes %abi_encoded.temp.5 = (alloc bytes len uint32 8)
  17. // CHECK: writebuffer buffer:%abi_encoded.temp.5 offset:uint32 0 value:(load (struct (arg #0) field 0))
  18. // CHECK: writebuffer buffer:%abi_encoded.temp.5 offset:uint32 4 value:int32 102
  19. // CHECK: %success.temp.6 = external call::regular address:(load (struct (arg #0) field 1)) payload:%abi_encoded.temp.5 value:uint128 0 gas:uint64 0 accounts: seeds: contract|function:_ flags:
  20. // CHECK: block1: # noassert
  21. // CHECK: return
  22. // CHECK: block2: # doassert
  23. // CHECK: assert-failure
  24. // CHECK: block3: # ret_success
  25. // CHECK: ty:uint32 %temp.7 = (builtin ArrayLength ((external call return data)))
  26. // CHECK: branchcond (unsigned uint32 8 <= %temp.7), block6, block7
  27. // CHECK: block6: # inbounds
  28. // CHECK: ty:uint64 %temp.8 = (builtin ReadFromBuffer ((external call return data), uint32 0))
  29. // CHECK: branchcond (unsigned less uint32 8 < %temp.7), block8, block9
  30. // CHECK: block7: # out_of_bounds
  31. // CHECK: assert-failure
  32. // CHECK: block8: # not_all_bytes_read
  33. // CHECK: assert-failure
  34. }
  35. // BEGIN-CHECK: ExternalFunctions::ExternalFunctions::function::storage_callback
  36. function storage_callback() public {
  37. // CHECK: %temp.9 = load storage slot(uint256 0) ty:function(int32) external returns (uint64)
  38. // CHECK: ty:bytes %abi_encoded.temp.10 = (alloc bytes len uint32 40)
  39. // CHECK: writebuffer buffer:%abi_encoded.temp.10 offset:uint32 0 value:hex"f503f5fe"
  40. // CHECK: writebuffer buffer:%abi_encoded.temp.10 offset:uint32 4 value:(load (struct function(int32) external returns (uint64)(%temp.9) field 1))
  41. // CHECK: writebuffer buffer:%abi_encoded.temp.10 offset:uint32 36 value:(load (struct function(int32) external returns (uint64)(%temp.9) field 0))
  42. // CHECK: external call::regular address:(load (builtin GetAddress ())) payload:%abi_encoded.temp.10 value:uint128 0 gas:uint64 0 accounts: seeds:
  43. this.bar(func);
  44. }
  45. }
  46. contract CompactEncoding {
  47. // BEGIN-CHECK: CompactEncoding::CompactEncoding::function::vector_length
  48. function vector_length(string memory s) public {
  49. bytes memory enc = abi.encode(s);
  50. abi.decode(enc, (string));
  51. // CHECK: branchcond (unsigned more (builtin ArrayLength ((arg #0))) > uint32 1073741823), block6, block7
  52. // CHECK: block1: # small
  53. // CHECK: ty:uint32 %temp.25 = uint32 1
  54. // CHECK: branch block5
  55. // CHECK: block2: # medium
  56. // CHECK: ty:uint32 %temp.25 = uint32 2
  57. // CHECK: branch block5
  58. // CHECK: block3: # medium_or_big
  59. // CHECK: branchcond (unsigned more (builtin ArrayLength ((arg #0))) > uint32 16383), block4, block2
  60. // CHECK: block4: # big
  61. // CHECK: ty:uint32 %temp.25 = uint32 4
  62. // CHECK: branch block5
  63. // CHECK: block5: # done
  64. // CHECK: ty:bytes %abi_encoded.temp.26 = (alloc bytes len (%temp.25 + (builtin ArrayLength ((arg #0)))))
  65. // CHECK: ty:uint32 %temp.27 = (builtin ArrayLength ((arg #0)))
  66. // CHECK: branchcond (unsigned more %temp.27 > uint32 1073741823), block13, block14
  67. // CHECK: block6: # fail
  68. // CHECK: assert-failure
  69. // CHECK: block7: # prepare
  70. // CHECK: branchcond (unsigned more (builtin ArrayLength ((arg #0))) > uint32 63), block3, block1
  71. // CHECK: block8: # small
  72. // CHECK: writebuffer buffer:%abi_encoded.temp.26 offset:uint32 0 value:(trunc uint8 (%temp.27 * uint32 4))
  73. // CHECK: ty:uint32 %temp.28 = uint32 1
  74. // CHECK: branch block12
  75. // CHECK: block9: # medium
  76. // CHECK: writebuffer buffer:%abi_encoded.temp.26 offset:uint32 0 value:(trunc uint16 ((%temp.27 * uint32 4) | uint32 1))
  77. // CHECK: ty:uint32 %temp.28 = uint32 2
  78. // CHECK: branch block12
  79. // CHECK: block10: # medium_or_big
  80. // CHECK: branchcond (unsigned more %temp.27 > uint32 16383), block11, block9
  81. // CHECK: block11: # big
  82. // CHECK: writebuffer buffer:%abi_encoded.temp.26 offset:uint32 0 value:((%temp.27 * uint32 4) | uint32 2)
  83. // CHECK: ty:uint32 %temp.28 = uint32 4
  84. // CHECK: branch block12
  85. // CHECK: block12: # done
  86. // CHECK: memcpy src: (arg #0), dest: (advance ptr: %abi_encoded.temp.26, by: (uint32 0 + %temp.28)), bytes_len: %temp.27
  87. // CHECK: ty:bytes %enc = %abi_encoded.temp.26
  88. // CHECK: ty:uint32 %temp.29 = (builtin ArrayLength (%enc))
  89. // CHECK: ty:uint32 %temp.31 = (zext uint32 (builtin ReadFromBuffer (%enc, uint32 0)))
  90. // CHECK: switch (%temp.31 & uint32 3):
  91. // CHECK: case uint32 0: goto block #15
  92. // CHECK: case uint32 1: goto block #16
  93. // CHECK: case uint32 2: goto block #17
  94. // CHECK: default: goto block #18
  95. // CHECK: block13: # fail
  96. // CHECK: assert-failure
  97. // CHECK: block14: # prepare
  98. // CHECK: branchcond (unsigned more %temp.27 > uint32 63), block10, block8
  99. // CHECK: block15: # case_0
  100. // CHECK: ty:uint32 %temp.30 = (%temp.31 >> uint32 2)
  101. // CHECK: ty:uint32 %temp.31 = uint32 1
  102. // CHECK: branch block19
  103. // CHECK: block16: # case_1
  104. // CHECK: ty:uint32 %temp.30 = ((zext uint32 (builtin ReadFromBuffer (%enc, uint32 0))) >> uint32 2)
  105. // CHECK: ty:uint32 %temp.31 = uint32 2
  106. // CHECK: branch block19
  107. // CHECK: block17: # case_2
  108. // CHECK: ty:uint32 %temp.30 = ((builtin ReadFromBuffer (%enc, uint32 0)) >> uint32 2)
  109. // CHECK: ty:uint32 %temp.31 = uint32 4
  110. // CHECK: branch block19
  111. // CHECK: block18: # case_default
  112. // CHECK: assert-failure
  113. // CHECK: block19: # done
  114. // CHECK: branchcond (unsigned (uint32 0 + %temp.31) <= %temp.29), block20, block21
  115. // CHECK: block20: # inbounds
  116. // CHECK: branchcond (unsigned (uint32 0 + (%temp.30 + %temp.31)) <= %temp.29), block22, block23
  117. // CHECK: block21: # out_of_bounds
  118. // CHECK: assert-failure
  119. // CHECK: block22: # inbounds
  120. // CHECK: ty:string %temp.32 = (alloc string len %temp.30)
  121. // CHECK: memcpy src: (advance ptr: %enc, by: (uint32 0 + %temp.31)), dest: %temp.32, bytes_len: %temp.30
  122. // CHECK: branchcond (unsigned less (uint32 0 + (%temp.30 + %temp.31)) < %temp.29), block24, block25
  123. // CHECK: block23: # out_of_bounds
  124. // CHECK: assert-failure
  125. // CHECK: block24: # not_all_bytes_read
  126. // CHECK: assert-failure
  127. }
  128. }