Replaced tabs with spaces

This commit is contained in:
Denton Liu 2016-05-11 15:55:07 -04:00
parent d6f05a6d36
commit 51fe1bd9c2

View File

@ -246,8 +246,8 @@ arising when writing manual assembly by the following features:
We now want to describe the inline assembly language in detail. We now want to describe the inline assembly language in detail.
.. warning:: .. warning::
Inline assembly is still a relatively new feature and might change if it does not prove useful, Inline assembly is still a relatively new feature and might change if it does not prove useful,
so please try to keep up to date. so please try to keep up to date.
Example Example
------- -------
@ -258,23 +258,23 @@ idea is that assembly libraries will be used to enhance the language in such way
.. code:: .. code::
library GetCode { library GetCode {
function at(address _addr) returns (bytes o_code) { function at(address _addr) returns (bytes o_code) {
assembly { assembly {
// retrieve the size of the code, this needs assembly // retrieve the size of the code, this needs assembly
let size := extcodesize(_addr) let size := extcodesize(_addr)
// allocate output byte array - this could also be done without assembly // allocate output byte array - this could also be done without assembly
// by using o_code = new bytes(size) // by using o_code = new bytes(size)
o_code := mload(0x40) o_code := mload(0x40)
// new "memory end" including padding // new "memory end" including padding
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), bnot(0x1f))))
// store length in memory // store length in memory
mstore(o_code, size) mstore(o_code, size)
// actually retrieve the code, this needs assembly // actually retrieve the code, this needs assembly
extcodecopy(_addr, add(o_code, 0x20), 0, size) extcodecopy(_addr, add(o_code, 0x20), 0, size)
} }
} }
} }
Inline assemmbly could also be beneficial in cases where the optimizer fails to produce Inline assemmbly could also be beneficial in cases where the optimizer fails to produce
efficient code. Please be aware that assembly is much more difficult to write because efficient code. Please be aware that assembly is much more difficult to write because
@ -283,24 +283,24 @@ you really know what you are doing.
.. code:: .. code::
library VectorSum { library VectorSum {
// This function is less efficient because the optimizer currently fails to // This function is less efficient because the optimizer currently fails to
// remove the bounds checks in array access. // remove the bounds checks in array access.
function sumSolidity(uint[] _data) returns (uint o_sum) { function sumSolidity(uint[] _data) returns (uint o_sum) {
for (uint i = 0; i < _data.length; ++i) for (uint i = 0; i < _data.length; ++i)
o_sum += _data[i]; o_sum += _data[i];
} }
// We know that we only access the array in bounds, so we can avoid the check. // We know that we only access the array in bounds, so we can avoid the check.
// 0x20 needs to be added to an array because the first slot contains the // 0x20 needs to be added to an array because the first slot contains the
// array length. // array length.
function sumAsm(uint[] _data) returns (uint o_sum) { function sumAsm(uint[] _data) returns (uint o_sum) {
for (uint i = 0; i < _data.length; ++i) { for (uint i = 0; i < _data.length; ++i) {
assembly { assembly {
o_sum := mload(add(add(_data, 0x20), i)) o_sum := mload(add(add(_data, 0x20), i))
} }
} }
} }
} }
Syntax Syntax
------ ------
@ -487,7 +487,7 @@ Strings are stored left-aligned and cannot be longer than 32 bytes.
.. code:: .. code::
assembly { 2 3 add "abc" and } assembly { 2 3 add "abc" and }
Functional Style Functional Style
----------------- -----------------
@ -497,7 +497,7 @@ adding `3` to the contents in memory at position `0x80` would be
.. code:: .. code::
3 0x80 mload add 0x80 mstore 3 0x80 mload add 0x80 mstore
As it is often hard to see what the actual arguments for certain opcodes are, As it is often hard to see what the actual arguments for certain opcodes are,
Solidity inline assembly also provides a "functional style" notation where the same code Solidity inline assembly also provides a "functional style" notation where the same code
@ -505,7 +505,7 @@ would be written as follows
.. code:: .. code::
mstore(0x80, add(mload(0x80), 3)) mstore(0x80, add(mload(0x80), 3))
Functional style and instructional style can be mixed, but any opcode inside a Functional style and instructional style can be mixed, but any opcode inside a
functional style expression has to return exactly one stack slot (most of the opcodes do). functional style expression has to return exactly one stack slot (most of the opcodes do).
@ -536,18 +536,18 @@ It is planned that the stack height changes can be specified in inline assembly.
.. code:: .. code::
contract c { contract c {
uint b; uint b;
function f(uint x) returns (uint r) { function f(uint x) returns (uint r) {
assembly { assembly {
b pop // remove the offset, we know it is zero b pop // remove the offset, we know it is zero
sload sload
x x
mul mul
=: r // assign to return variable r =: r // assign to return variable r
} }
} }
} }
Labels Labels
------ ------
@ -558,19 +558,19 @@ jumps easier. The following code computes an element in the Fibonacci series.
.. code:: .. code::
{ {
let n := calldataload(4) let n := calldataload(4)
let a := 1 let a := 1
let b := a let b := a
loop: loop:
jumpi(loopend, eq(n, 0)) jumpi(loopend, eq(n, 0))
a add swap1 a add swap1
n := sub(n, 1) n := sub(n, 1)
jump(loop) jump(loop)
loopend: loopend:
mstore(0, a) mstore(0, a)
return(0, 0x20) return(0, 0x20)
} }
Please note that automatically accessing stack variables can only work if the Please note that automatically accessing stack variables can only work if the
assembler knows the current stack height. This fails to work if the jump source assembler knows the current stack height. This fails to work if the jump source
@ -583,19 +583,19 @@ will have a wrong impression about the stack height at label `two`:
.. code:: .. code::
{ {
jump(two) jump(two)
one: one:
// Here the stack height is 1 (because we pushed 7), // Here the stack height is 1 (because we pushed 7),
// but the assembler thinks it is 0 because it reads // but the assembler thinks it is 0 because it reads
// from top to bottom. // from top to bottom.
// Accessing stack variables here will lead to errors. // Accessing stack variables here will lead to errors.
jump(three) jump(three)
two: two:
7 // push something onto the stack 7 // push something onto the stack
jump(one) jump(one)
three: three:
} }
Declaring Assembly-Local Variables Declaring Assembly-Local Variables
@ -610,19 +610,19 @@ be just `0`, but it can also be a complex functional-style expression.
.. code:: .. code::
contract c { contract c {
function f(uint x) returns (uint b) { function f(uint x) returns (uint b) {
assembly { assembly {
let v := add(x, 1) let v := add(x, 1)
mstore(0x80, v) mstore(0x80, v)
{ {
let y := add(sload(v), 1) let y := add(sload(v), 1)
b := y b := y
} // y is "deallocated" here } // y is "deallocated" here
b := add(b, v) b := add(b, v)
} // v is "deallocated" here } // v is "deallocated" here
} }
} }
Assignments Assignments
@ -640,12 +640,12 @@ For both ways, the colon points to the name of the variable.
.. code:: .. code::
assembly { assembly {
let v := 0 // functional-style assignment as part of variable declaration let v := 0 // functional-style assignment as part of variable declaration
let g := add(v, 2) let g := add(v, 2)
sload(10) sload(10)
=: v // instruction style assignment, puts the result of sload(10) into v =: v // instruction style assignment, puts the result of sload(10) into v
} }
Things to Avoid Things to Avoid
@ -681,6 +681,6 @@ arrays are pointers to memory arrays. The length of a dynamic array is stored at
first slot of the array and then only the array elements follow. first slot of the array and then only the array elements follow.
.. warning:: .. warning::
Statically-sized memory arrays do not have a length field, but it will be added soon Statically-sized memory arrays do not have a length field, but it will be added soon
to allow better convertibility between statically- and dynamically-sized arrays, so to allow better convertibility between statically- and dynamically-sized arrays, so
please do not rely on that. please do not rely on that.