diff options
author | chriseth <c@ethdev.com> | 2017-02-16 16:44:05 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2017-03-03 22:41:01 +0800 |
commit | f4f82615b129974c811288a5af8e40c95548f11b (patch) | |
tree | b3c0d9d8d9000fee0b251a80868d802caaa25e2c /docs/assembly.rst | |
parent | 25dcfa3480b2265d6dbb798849bfaadebc9a405c (diff) | |
download | dexon-solidity-f4f82615b129974c811288a5af8e40c95548f11b.tar.gz dexon-solidity-f4f82615b129974c811288a5af8e40c95548f11b.tar.zst dexon-solidity-f4f82615b129974c811288a5af8e40c95548f11b.zip |
Updated documentation.
Diffstat (limited to 'docs/assembly.rst')
-rw-r--r-- | docs/assembly.rst | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/docs/assembly.rst b/docs/assembly.rst index 23ccfcbe..b28216f1 100644 --- a/docs/assembly.rst +++ b/docs/assembly.rst @@ -361,7 +361,9 @@ 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. The following code computes an element in the Fibonacci series. +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 +(see below). The following code computes an element in the Fibonacci series. .. code:: @@ -391,12 +393,35 @@ will have a wrong impression about the stack height at label ``two``: .. code:: { + let x := 8 jump(two) one: - // Here the stack height is 1 (because we pushed 7), - // but the assembler thinks it is 0 because it reads + // Here the stack height is 2 (because we pushed x and 7), + // but the assembler thinks it is 1 because it reads // from top to bottom. - // Accessing stack variables here will lead to errors. + // Accessing the stack variable x here will lead to errors. + x := 9 + jump(three) + two: + 7 // push something onto the stack + jump(one) + three: + } + +This problem can be fixed by manually adjusting the stack height for the +assembler - you can provide a stack height delta that is added +to the stack height just prior to the label. +Note that you will not have to care about these things if you just use +loops and assembly-level functions. + +.. code:: + + { + let x := 8 + jump(two) + one[1]: + // Now the stack height is correctly adjusted. + x := 9 jump(three) two: 7 // push something onto the stack @@ -464,6 +489,9 @@ is performed by replacing the variable's value on the stack by the new value. Switch ------ +.. note:: + Switch is not yet implemented. + You can use a switch statement as a very basic version of "if/else". It takes the value of an expression and compares it to several constants. The branch corresponding to the matching constant is taken. Contrary to the @@ -491,6 +519,9 @@ case does require them. Loops ----- +.. note:: + Loops are not yet implemented. + Assembly supports a simple for-style loop. For-style loops have a header containing an initializing part, a condition and a post-iteration part. The condition has to be a functional-style expression, while @@ -512,6 +543,9 @@ The following example computes the sum of an area in memory. Functions --------- +.. note:: + Functions are not yet implemented. + Assembly allows the definition of low-level functions. These take their arguments (and a return PC) from the stack and also put the results onto the stack. Calling a function looks the same way as executing a functional-style @@ -610,8 +644,7 @@ which follow very simple and regular scoping rules and cleanup of local variable Scoping: An identifier that is declared (label, variable, function, assembly) is only visible in the block where it was declared (including nested blocks inside the current block). It is not legal to access local variables across -function borders, even if they would be in scope. Shadowing is allowed, but -two identifiers with the same name cannot be declared in the same block. +function borders, even if they would be in scope. Shadowing is not allowed. Local variables cannot be accessed before they were declared, but labels, functions and assemblies can. Assemblies are special blocks that are used for e.g. returning runtime code or creating contracts. No identifier from an @@ -624,7 +657,7 @@ flow path. Whenever a local variable is referenced, the code generator needs to know its current relative position in the stack and thus it needs to keep track of the current so-called stack height. At the end of a block, this implicit stack height is always reduced by the number -of local variables whether ther is a continuing control flow or not. +of local variables whether there is a continuing control flow or not. This means that the stack height before and after the block should be the same. If this is not the case, a warning is issued, @@ -805,7 +838,7 @@ Grammar:: IdentifierOrList = Identifier | '(' IdentifierList ')' IdentifierList = Identifier ( ',' Identifier)* AssemblyAssignment = '=:' Identifier - LabelDefinition = Identifier ( '[' ( IdentifierList | NumberLiteral ) ']' )? ':' + LabelDefinition = Identifier ( '[' ( IdentifierList? | NumberLiteral ) ']' )? ':' AssemblySwitch = 'switch' FunctionalAssemblyExpression AssemblyCase* ( 'default' ':' AssemblyBlock )? AssemblyCase = 'case' FunctionalAssemblyExpression ':' AssemblyBlock @@ -947,11 +980,14 @@ Pseudocode:: POP LabelDefinition(name [id1, ..., idn] :) -> JUMPDEST - // register new variables id1, ..., idn and set the stack height to - // stack_height_at_block_start + number_of_local_variables + // register new variables id1, ..., idn and adjust the assumed stack + // height such that it matches the stack height at the beginning of + // the block plus all local variables including the just registered + // ones where idn is at the stack top. If n is zero, resets the stack + // height to just the local variables. LabelDefinition(name [number] :) -> JUMPDEST - // adjust stack height by +number (can be negative) + // adjust stack height by the relative amount "number" (can be negative) NumberLiteral(num) -> PUSH<num interpreted as decimal and right-aligned> HexLiteral(lit) -> |