diff options
author | chriseth <chris@ethereum.org> | 2017-11-21 20:36:41 +0800 |
---|---|---|
committer | chriseth <chris@ethereum.org> | 2017-11-22 23:25:24 +0800 |
commit | 6dbc34e16ee8bda0e156ccb20a3fb8cb6ff52c92 (patch) | |
tree | c7e5c438ef7517293c08f4e0516f8c38c9a7c5c6 /docs/assembly.rst | |
parent | ff229ab05a43d113bcd2de79f25caf52017c3486 (diff) | |
download | dexon-solidity-6dbc34e16ee8bda0e156ccb20a3fb8cb6ff52c92.tar.gz dexon-solidity-6dbc34e16ee8bda0e156ccb20a3fb8cb6ff52c92.tar.zst dexon-solidity-6dbc34e16ee8bda0e156ccb20a3fb8cb6ff52c92.zip |
If statement for Iulia / inline assembly.
Diffstat (limited to 'docs/assembly.rst')
-rw-r--r-- | docs/assembly.rst | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/docs/assembly.rst b/docs/assembly.rst index 00bfb388..c233985b 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -26,6 +26,7 @@ arising when writing manual assembly by the following features: * access to external variables: ``function f(uint x) { assembly { x := sub(x, 1) } }`` * labels: ``let x := 10 repeat: x := sub(x, 1) jumpi(repeat, eq(x, 0))`` * loops: ``for { let i := 0 } lt(i, x) { i := add(i, 1) } { y := mul(2, y) }`` +* if statements: ``if slt(x, 0) { x := sub(0, x) }`` * switch statements: ``switch x case 0 { y := mul(x, 2) } default { y := 0 }`` * function calls: ``function f(x) -> y { switch x case 0 { y := 1 } default { y := mul(x, f(sub(x, 1))) } }`` @@ -400,7 +401,7 @@ Labels Another problem in EVM assembly is that ``jump`` and ``jumpi`` use absolute addresses which can change easily. Solidity inline assembly provides labels to make the use of jumps easier. Note that labels are a low-level feature and it is possible to write -efficient assembly without labels, just using assembly functions, loops and switch instructions +efficient assembly without labels, just using assembly functions, loops, if and switch instructions (see below). The following code computes an element in the Fibonacci series. .. code:: @@ -523,6 +524,21 @@ is performed by replacing the variable's value on the stack by the new value. =: v // instruction style assignment, puts the result of sload(10) into v } +If +-- + +The if statement can be used for conditionally executing code. +There is no "else" part, consider using "switch" (see below) if +you need multiple alternatives. + +.. code:: + + { + if eq(value, 0) { revert(0, 0) } + } + +The curly braces for the body are required. + Switch ------ @@ -622,7 +638,7 @@ Things to Avoid --------------- Inline assembly might have a quite high-level look, but it actually is extremely -low-level. Function calls, loops and switches are converted by simple +low-level. Function calls, loops, ifs and switches are converted by simple rewriting rules and after that, the only thing the assembler does for you is re-arranging functional-style opcodes, managing jump labels, counting stack height for variable access and removing stack slots for assembly-local variables when the end @@ -669,7 +685,7 @@ for the Solidity compiler. In this form, it tries to achieve several goals: 3. Control flow should be easy to detect to help in formal verification and optimization. In order to achieve the first and last goal, assembly provides high-level constructs -like ``for`` loops, ``switch`` statements and function calls. It should be possible +like ``for`` loops, ``if`` and ``switch`` statements and function calls. It should be possible to write assembly programs that do not make use of explicit ``SWAP``, ``DUP``, ``JUMP`` and ``JUMPI`` statements, because the first two obfuscate the data flow and the last two obfuscate control flow. Furthermore, functional statements of @@ -875,6 +891,7 @@ Grammar:: FunctionalAssemblyAssignment | AssemblyAssignment | LabelDefinition | + AssemblyIf | AssemblySwitch | AssemblyFunctionDefinition | AssemblyFor | @@ -891,6 +908,7 @@ Grammar:: IdentifierList = Identifier ( ',' Identifier)* AssemblyAssignment = '=:' Identifier LabelDefinition = Identifier ':' + AssemblyIf = 'if' FunctionalAssemblyExpression AssemblyBlock AssemblySwitch = 'switch' FunctionalAssemblyExpression AssemblyCase* ( 'default' AssemblyBlock )? AssemblyCase = 'case' FunctionalAssemblyExpression AssemblyBlock |