scale.sol 7.3 KB

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