Skip to content

Commit 00cfbdf

Browse files
authored
Add yul documentation (#855)
Signed-off-by: Lucas Steuernagel <lucas.tnagel@gmail.com>
1 parent 2e02b38 commit 00cfbdf

12 files changed

+603
-11
lines changed

.github/workflows/test.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@ jobs:
3333
docs:
3434
name: Docs
3535
runs-on: ubuntu-latest
36-
container: ubuntu:22.04
36+
container: ubuntu:20.04
3737
steps:
3838
- name: Checkout sources
3939
uses: actions/checkout@v2
40-
- name: Install sphinx
40+
- name: Install Python
4141
run: |
42-
export DEBIAN_FRONTEND=noninteractive
4342
apt-get update
44-
apt-get install -y python3-sphinx python3-sphinx-rtd-theme
43+
apt-get install -y python3-pip
44+
- name: Install Docs requiremets
45+
run : |
46+
pip install -r requirements.txt
4547
- name: Build docs
4648
run: make html
4749
working-directory: docs

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ will be documented here.
66

77
### Added
88
- Added spl-token integration for Solana
9+
- Solang now generates code for inline assembly, including many Yul builtins
910

1011
### Changed
1112
- The documentation has been re-arranged for readability.

README.md

+7-7
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,13 @@ Here is a brief description of what we envision for the next versions.
144144

145145
### V0.4
146146

147-
| Milestone | Status |
148-
|-----------------------------------|--------------|
149-
| Call Solidity from Rust | Not started |
150-
| Generate code for inline assembly | Not started |
151-
| Improve management over optimization passes | Not Started |
152-
| Dead code elimination | Not started |
153-
| ewasm target | Not started |
147+
| Milestone | Status |
148+
|-----------------------------------|-------------|
149+
| Call Solidity from Rust | Not started |
150+
| Generate code for inline assembly | Completed |
151+
| Improve management over optimization passes | Not Started |
152+
| Dead code elimination | Not started |
153+
| ewasm target | Not started |
154154

155155

156156

docs/conf.py

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
# sys.path.insert(0, os.path.abspath('.'))
1616
import os
1717

18+
from pygments_lexer_solidity import SolidityLexer, YulLexer
19+
20+
def setup(sphinx):
21+
sphinx.add_lexer('Solidity', SolidityLexer)
22+
sphinx.add_lexer('Yul', YulLexer)
23+
1824
# -- Project information -----------------------------------------------------
1925

2026
project = 'Solang Solidity Compiler'

docs/index.rst

+11
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ Contents
5656
language/managing_values.rst
5757
language/builtins.rst
5858
language/tags.rst
59+
language/inline_assembly.rst
60+
61+
.. toctree::
62+
:maxdepth: 3
63+
:caption: Yul language
64+
65+
yul_language/yul.rst
66+
yul_language/statements.rst
67+
yul_language/types.rst
68+
yul_language/functions.rst
69+
yul_language/builtins.rst
5970

6071
.. toctree::
6172
:maxdepth: 3

docs/language/inline_assembly.rst

+116
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
Inline Assembly
2+
===============
3+
4+
In Solidity functions, developers are allowed to write assembly blocks containing Yul code. For more information about
5+
the Yul programming language, please refer to the :ref:`yul section <yul_section>`.
6+
7+
In an assembly block, you can access solidity local variables freely and modify them as well. Bear in mind, however,
8+
that reference types like strings, vectors and structs are memory addresses in yul, so manipulating them can be unsafe
9+
unless done correctly. Any assignment to those variables will change the address the reference points to and
10+
may cause the program to crash if not managed correctly.
11+
12+
.. code-block:: solidity
13+
14+
contract foo {
15+
struct test_stru {
16+
uint a;
17+
uint b;
18+
}
19+
20+
function bar(uint64 a) public pure returns (uint64 ret) {
21+
uint64 b = 6;
22+
uint64[] memory vec;
23+
vec.push(4);
24+
string str = "cafe";
25+
test_stru tts = test_stru({a: 1, b: 2});
26+
assembly {
27+
// The following statements modify variables directly
28+
a := add(a, 3)
29+
b := mul(b, 2)
30+
ret := sub(a, b)
31+
32+
// The following modify the reference address
33+
str := 5
34+
vec := 6
35+
tts := 7
36+
}
37+
38+
// Any access to 'str', 'vec' or 'tts' here may crash the program.
39+
}
40+
41+
}
42+
43+
44+
Storage variables cannot be accessed nor assigned directly. You must use the ``.slot`` and ``.offset`` suffix to use storage
45+
variables. Storage variables should be read with the ``sload`` and saved with ``sstore`` builtins, but they are not implemented yet.
46+
Solang does not implement offsets for storage variables, so the ``.offset`` suffix will always return zero.
47+
Assignments to the offset are only allowed to Solidity local variables that are a reference to the storage.
48+
49+
.. code-block:: solidity
50+
51+
contract foo {
52+
struct test_stru {
53+
uint a;
54+
uint b;
55+
}
56+
57+
test_stru storage_struct;
58+
function bar() public pure {
59+
test_stru storage tts = storage_struct;
60+
assembly {
61+
// The variables 'a' and 'b' contain zero
62+
let a := storage_struct.offset
63+
let b := tts.offset
64+
65+
// This changes the reference slot of 'tts'
66+
tts.slot := 5
67+
}
68+
}
69+
}
70+
71+
72+
73+
Dynamic calldata arrays should be accessed with the ``.offset`` and ``.length`` suffixes. The offset suffix returns the
74+
array's memory address. Assignments to ``.length`` are not yet implemented.
75+
76+
.. code-block:: solidity
77+
78+
contract foo {
79+
function bar(int[] calldata vl) public pure {
80+
test_stru storage tts = storage_struct;
81+
assembly {
82+
// 'a' contains vl memory address
83+
let a := vl.offset
84+
85+
// 'b' contains vl length
86+
let b := vl.length
87+
88+
// This will change the reference of vl
89+
vl.offset := 5
90+
}
91+
// Any usage of vl here may crash the program
92+
}
93+
}
94+
95+
96+
External functions in Yul can be accessed and modified with the ``.selector`` and ``.address`` suffixes. The assignment
97+
to those values, however, are not yet implemented.
98+
99+
.. code-block:: solidity
100+
101+
contract foo {
102+
function sum(uint64 a, uint64 b) public pure returns (uint64) {
103+
return a + b;
104+
}
105+
106+
function bar() public view {
107+
function (uint64, uint64) external returns (uint64) fPtr = this.sum;
108+
assembly {
109+
// 'a' contains 'sum' selector
110+
let a := fPtr.selector
111+
112+
// 'b' contains 'sum' address
113+
let b := vl.address
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)