Describe built-in Julia functions

This commit is contained in:
Alex Beregszaszi 2017-04-18 13:41:16 +01:00
parent 2a91eb9538
commit c3a6db7256

View File

@ -18,7 +18,7 @@ for-loops, switch-statements, expressions and assignments to variables.
JULIA in itself does not even provide operators. If the EVM is targeted, JULIA in itself does not even provide operators. If the EVM is targeted,
opcodes will be available as built-in functions, but they can be reimplemented opcodes will be available as built-in functions, but they can be reimplemented
if the backend changes. if the backend changes. For a list of mandatory built-in functions, see the section below.
The following example program assumes that the EVM opcodes ``mul``, ``div`` The following example program assumes that the EVM opcodes ``mul``, ``div``
and ``mod`` are available either natively or as functions and computes exponentiation. and ``mod`` are available either natively or as functions and computes exponentiation.
@ -187,3 +187,165 @@ For ``(S1, z) = E(S, y)`` let ``(S2, w) = E(S1, x)``. TODO
where hex is the hexadecimal decoding function where hex is the hexadecimal decoding function
E(G, L, n: DecimalNumber) = G, L, dec(n), E(G, L, n: DecimalNumber) = G, L, dec(n),
where dec is the decimal decoding function where dec is the decimal decoding function
Low-level Functions
-------------------
The following functions must be available:
+---------------------------------------------------------------------------------------------------------------+
| *Arithmetics* |
+---------------------------------------------------------------------------------------------------------------+
| add256(x:256, y:256) -> z:256 | x + y |
+---------------------------------------------------------------------------------------------------------------+
| sub256(x:256, y:256) -> z:256 | x - y |
+---------------------------------------------------------------------------------------------------------------+
| mul256(x:256, y:256) -> z:256 | x * y |
+---------------------------------------------------------------------------------------------------------------+
| div256(x:256, y:256) -> z:256 | x / y |
+---------------------------------------------------------------------------------------------------------------+
| sdiv256(x:256, y:256) -> z:256 | x / y, for signed numbers in two's complement |
+---------------------------------------------------------------------------------------------------------------+
| mod256(x:256, y:256) -> z:256 | x % y |
+---------------------------------------------------------------------------------------------------------------+
| smod256(x:256, y:256) -> z:256 | x % y, for signed numbers in two's complement |
+---------------------------------------------------------------------------------------------------------------+
| signextend256(i:256, x:256) -> z:256 | sign extend from (i*8+7)th bit counting from least significant |
+---------------------------------------------------------------------------------------------------------------+
| exp256(x:256, y:256) -> z:256 | x to the power of y |
+---------------------------------------------------------------------------------------------------------------+
| addmod256(x:256, y:256, m:256) -> z:256 | (x + y) % m with arbitrary precision arithmetics |
+---------------------------------------------------------------------------------------------------------------+
| mulmod256(x:256, y:256, m:256) -> z:256 | (x * y) % m with arbitrary precision arithmetics |
+---------------------------------------------------------------------------------------------------------------+
| lt256(x:256, y:256) -> z:bool | 1 if x < y, 0 otherwise |
+---------------------------------------------------------------------------------------------------------------+
| gt256(x:256, y:256) -> z:bool | 1 if x > y, 0 otherwise |
+---------------------------------------------------------------------------------------------------------------+
| slt256(x:256, y:256) -> z:bool | 1 if x < y, 0 otherwise, for signed numbers in two's complement |
+---------------------------------------------------------------------------------------------------------------+
| sgt256(x:256, y:256) -> z:bool | 1 if x > y, 0 otherwise, for signed numbers in two's complement |
+---------------------------------------------------------------------------------------------------------------+
| eq256(x:256, y:256) -> z:bool | 1 if x == y, 0 otherwise |
+---------------------------------------------------------------------------------------------------------------+
| not256(x:256) -> z:256 | ~x, every bit of x is negated |
+---------------------------------------------------------------------------------------------------------------+
| and256(x:256, y:256) -> z:256 | bitwise and of x and y |
+---------------------------------------------------------------------------------------------------------------+
| or256(x:256, y:256) -> z:256 | bitwise or of x and y |
+---------------------------------------------------------------------------------------------------------------+
| xor256(x:256, y:256) -> z:256 | bitwise xor of x and y |
+---------------------------------------------------------------------------------------------------------------+
| shl256(x:256, y:256) -> z:256 | logical left shift of x by y |
+---------------------------------------------------------------------------------------------------------------+
| shr256(x:256, y:256) -> z:256 | logical right shift of x by y |
+---------------------------------------------------------------------------------------------------------------+
| sar256(x:256, y:256) -> z:256 | arithmetic right shift of x by y |
+---------------------------------------------------------------------------------------------------------------+
| byte(n:256, x:256) -> v:256 | nth byte of x, where the most significant byte is the 0th byte |
| Cannot this be just replaced by and256(shr256(n, x), 0xff) and let it be optimised out by the EVM backend? |
+---------------------------------------------------------------------------------------------------------------+
| *Memory and storage* |
+---------------------------------------------------------------------------------------------------------------+
| mload(p:256) -> v:256 | mem[p..(p+32)) |
+---------------------------------------------------------------------------------------------------------------+
| mstore(p:256, v:256) | mem[p..(p+32)) := v |
+---------------------------------------------------------------------------------------------------------------+
| mstore8(p:256, v:256) | mem[p] := v & 0xff - only modifies a single byte |
+---------------------------------------------------------------------------------------------------------------+
| sload(p:256) -> v:256 | storage[p] |
+---------------------------------------------------------------------------------------------------------------+
| sstore(p:256, v:256) | storage[p] := v |
+---------------------------------------------------------------------------------------------------------------+
| msize() -> size:256 | size of memory, i.e. largest accessed memory index, albeit due |
| | due to the memory extension function, which extends by words, |
| | this will always be a multiple of 32 bytes |
+---------------------------------------------------------------------------------------------------------------+
| *Execution control* |
+---------------------------------------------------------------------------------------------------------------+
| create(v:256, p:256, s:256) | create new contract with code mem[p..(p+s)) and send v wei |
| | and return the new address |
+---------------------------------------------------------------------------------------------------------------+
| call(g:256, a:256, v:256, in:256, | call contract at address a with input mem[in..(in+insize)) |
| insize:256, out:256, outsize:256) -> r:256 | providing g gas and v wei and output area |
| | mem[out..(out+outsize)) returning 0 on error (eg. out of gas) |
| | and 1 on success |
+---------------------------------------------------------------------------------------------------------------+
| callcode(g:256, a:256, v:256, in:256, | identical to `call` but only use the code from a and stay |
| insize:256, out:256, outsize:256) -> r:256 | in the context of the current contract otherwise |
+---------------------------------------------------------------------------------------------------------------+
| delegatecall(g:256, a:256, in:256, | identical to `callcode` but also keep ``caller`` |
| insize:256, out:256, outsize:256) -> r:256 | and ``callvalue`` |
+---------------------------------------------------------------------------------------------------------------+
| stop() | stop execution, identical to return(0,0) |
| Perhaps it would make sense retiring this as it equals to return(0,0). It can be an optimisation by the EVM |
| backend. |
+---------------------------------------------------------------------------------------------------------------+
| abort() | abort (equals to invalid instruction on EVM) |
+---------------------------------------------------------------------------------------------------------------+
| return(p:256, s:256) | end execution, return data mem[p..(p+s)) |
+---------------------------------------------------------------------------------------------------------------+
| revert(p:256, s:256) | end execution, revert state changes, return data mem[p..(p+s)) |
+---------------------------------------------------------------------------------------------------------------+
| selfdestruct(a:256) | end execution, destroy current contract and send funds to a |
+---------------------------------------------------------------------------------------------------------------+
| log0(p:256, s:256) | log without topics and data mem[p..(p+s)) |
+---------------------------------------------------------------------------------------------------------------+
| log1(p:256, s:256, t1:256) | log with topic t1 and data mem[p..(p+s)) |
+---------------------------------------------------------------------------------------------------------------+
| log2(p:256, s:256, t1:256, t2:256) | log with topics t1, t2 and data mem[p..(p+s)) |
+---------------------------------------------------------------------------------------------------------------+
| log3(p:256, s:256, t1:256, t2:256, | log with topics t, t2, t3 and data mem[p..(p+s)) |
| t3:256) | |
+---------------------------------------------------------------------------------------------------------------+
| log4(p:256, s:256, t1:256, t2:256, | log with topics t1, t2, t3, t4 and data mem[p..(p+s)) |
| t3:256, t4:256) | |
+---------------------------------------------------------------------------------------------------------------+
| *State queries* |
+---------------------------------------------------------------------------------------------------------------+
| blockcoinbase() -> address:256 | current mining beneficiary |
+---------------------------------------------------------------------------------------------------------------+
| blockdifficulty() -> difficulty:256 | difficulty of the current block |
+---------------------------------------------------------------------------------------------------------------+
| blockgaslimit() -> limit:256 | block gas limit of the current block |
+---------------------------------------------------------------------------------------------------------------+
| blockhash(b:256) -> hash:256 | hash of block nr b - only for last 256 blocks excluding current |
+---------------------------------------------------------------------------------------------------------------+
| blocknumber() -> block:256 | current block number |
+---------------------------------------------------------------------------------------------------------------+
| blocktimestamp() -> timestamp:256 | timestamp of the current block in seconds since the epoch |
+---------------------------------------------------------------------------------------------------------------+
| txorigin() -> address:256 | transaction sender |
+---------------------------------------------------------------------------------------------------------------+
| txgasprice() -> price:256 | gas price of the transaction |
+---------------------------------------------------------------------------------------------------------------+
| gasleft() -> gas:256 | gas still available to execution |
+---------------------------------------------------------------------------------------------------------------+
| balance(a:256) -> v:256 | wei balance at address a |
+---------------------------------------------------------------------------------------------------------------+
| this() -> address:256 | address of the current contract / execution context |
+---------------------------------------------------------------------------------------------------------------+
| caller() -> address:256 | call sender (excluding delegatecall) |
+---------------------------------------------------------------------------------------------------------------+
| callvalue() -> v:256 | wei sent together with the current call |
+---------------------------------------------------------------------------------------------------------------+
| calldataload(p:256) -> v:256 | call data starting from position p (32 bytes) |
+---------------------------------------------------------------------------------------------------------------+
| calldatasize() -> v:256 | size of call data in bytes |
+---------------------------------------------------------------------------------------------------------------+
| calldatacopy(t:256, f:256, s:256) | copy s bytes from calldata at position f to mem at position t |
+---------------------------------------------------------------------------------------------------------------+
| codesize() -> size:256 | size of the code of the current contract / execution context |
+---------------------------------------------------------------------------------------------------------------+
| codecopy(t:256, f:256, s:256) | copy s bytes from code at position f to mem at position t |
+---------------------------------------------------------------------------------------------------------------+
| extcodesize(a:256) -> size:256 | size of the code at address a |
+---------------------------------------------------------------------------------------------------------------+
| extcodecopy(a:256, t:256, f:256, s:256) | like codecopy(t, f, s) but take code at address a |
+---------------------------------------------------------------------------------------------------------------+
| *Others* |
+---------------------------------------------------------------------------------------------------------------+
| discard256(unused:256) | discard value |
+---------------------------------------------------------------------------------------------------------------+
| sha3(p:256, s:256) -> v:256 | keccak(mem[p...(p+s))) |
+---------------------------------------------------------------------------------------------------------------+