mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge remote-tracking branch 'origin/develop' into release
This commit is contained in:
commit
822622cf5b
10
.travis.yml
10
.travis.yml
@ -6,22 +6,22 @@
|
||||
# http://solidity.readthedocs.org
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of cpp-ethereum.
|
||||
# This file is part of solidity.
|
||||
#
|
||||
# cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
# solidity is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# cpp-ethereum is distributed in the hope that it will be useful,
|
||||
# solidity is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>
|
||||
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# (c) 2016 cpp-ethereum contributors.
|
||||
# (c) 2016 solidity contributors.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
language: cpp
|
||||
|
@ -8,7 +8,7 @@ include(EthPolicy)
|
||||
eth_policy()
|
||||
|
||||
# project name and version should be set after cmake_policy CMP0048
|
||||
set(PROJECT_VERSION "0.4.6")
|
||||
set(PROJECT_VERSION "0.4.7")
|
||||
project(solidity VERSION ${PROJECT_VERSION})
|
||||
|
||||
# Let's find our dependencies
|
||||
|
19
Changelog.md
19
Changelog.md
@ -1,7 +1,24 @@
|
||||
### 0.4.7 (2016-12-15)
|
||||
|
||||
Features:
|
||||
* Bitshift operators.
|
||||
* Type checker: Warn when ``msg.value`` is used in non-payable function.
|
||||
* Code generator: Inject the Swarm hash of a metadata file into the bytecode.
|
||||
* Code generator: Replace expensive memcpy precompile by simple assembly loop.
|
||||
* Optimizer: Some dead code elimination.
|
||||
|
||||
Bugfixes:
|
||||
* Code generator: throw if calling the identity precompile failed during memory (array) copying.
|
||||
* Type checker: string literals that are not valid UTF-8 cannot be converted to string type
|
||||
* Code generator: any non-zero value given as a boolean argument is now converted into 1.
|
||||
* AST Json Converter: replace ``VariableDefinitionStatement`` nodes with ``VariableDeclarationStatement``
|
||||
* AST Json Converter: fix the camel case in ``ElementaryTypeNameExpression``
|
||||
* AST Json Converter: replace ``public`` field with ``visibility`` in the function definition nodes
|
||||
|
||||
### 0.4.6 (2016-11-22)
|
||||
|
||||
Bugfixes:
|
||||
* Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs
|
||||
* Optimizer: Knowledge about state was not correctly cleared for JUMPDESTs (introduced in 0.4.5)
|
||||
|
||||
### 0.4.5 (2016-11-21)
|
||||
|
||||
|
10
appveyor.yml
10
appveyor.yml
@ -9,22 +9,22 @@
|
||||
# sockets unconditionally at the time of writing.
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of cpp-ethereum.
|
||||
# This file is part of solidity.
|
||||
#
|
||||
# cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
# solidity is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# cpp-ethereum is distributed in the hope that it will be useful,
|
||||
# solidity is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>
|
||||
# along with solidity. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# (c) 2016 cpp-ethereum contributors.
|
||||
# (c) 2016 solidity contributors.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
branches:
|
||||
|
@ -155,6 +155,9 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --memory-init-file 0 -O3 -s LINKABLE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s NO_EXIT_RUNTIME=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_DYNAMIC_EXECUTION=1")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s NO_FILESYSTEM=1 -s AGGRESSIVE_VARIABLE_ELIMINATION=1")
|
||||
add_definitions(-DETH_EMSCRIPTEN=1)
|
||||
endif()
|
||||
endif()
|
||||
|
@ -56,9 +56,9 @@ copyright = '2016, Ethereum'
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
version = '0.4.6'
|
||||
version = '0.4.7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '0.4.6-develop'
|
||||
release = '0.4.7-develop'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -721,8 +721,10 @@ Details are given in the following example.
|
||||
NameReg(config.lookup(1)).register(name);
|
||||
}
|
||||
|
||||
// Functions can be overridden, both local and
|
||||
// message-based function calls take these overrides
|
||||
// Functions can be overridden by another function with the same name and
|
||||
// the same number/types of inputs. If the overriding function has different
|
||||
// types of output parameters, that causes an error.
|
||||
// Both local and message-based function calls take these overrides
|
||||
// into account.
|
||||
function kill() {
|
||||
if (msg.sender == owner) {
|
||||
|
@ -59,3 +59,18 @@ for this project. Also, even though we do CI testing, please test your code and
|
||||
ensure that it builds locally before submitting a pull request.
|
||||
|
||||
Thank you for your help!
|
||||
|
||||
Running the compiler tests
|
||||
==========================
|
||||
|
||||
Solidity includes different types of tests. They are included in the application
|
||||
called ``soltest``. Some of them require the ``cpp-ethereum`` client in testing mode.
|
||||
|
||||
To run ``cpp-ethereum`` in testing mode: ``eth --test -d /tmp/testeth``.
|
||||
|
||||
To run the tests: ``soltest -- --ipcpath /tmp/testeth/geth.ipc``.
|
||||
|
||||
To run a subset of tests, filters can be used:
|
||||
``soltest -t TestSuite/TestName -- --ipcpath /tmp/testeth/geth.ipc``, where ``TestName`` can be a wildcard ``*``.
|
||||
|
||||
Alternatively, there is a testing script at ``scripts/test.sh`` which executes all tests.
|
||||
|
@ -2,12 +2,62 @@
|
||||
Expressions and Control Structures
|
||||
##################################
|
||||
|
||||
.. index:: ! parameter, parameter;input, parameter;output
|
||||
|
||||
Input Parameters and Output Parameters
|
||||
======================================
|
||||
|
||||
As in Javascript, functions may take parameters as input;
|
||||
unlike in Javascript and C, they may also return arbitrary number of
|
||||
parameters as output.
|
||||
|
||||
Input Parameters
|
||||
----------------
|
||||
|
||||
The input parameters are declared the same way as variables are. As an
|
||||
exception, unused parameters can omit the variable name.
|
||||
For example, suppose we want our contract to
|
||||
accept one kind of external calls with two integers, we would write
|
||||
something like::
|
||||
|
||||
contract Simple {
|
||||
function taker(uint _a, uint _b) {
|
||||
// do something with _a and _b.
|
||||
}
|
||||
}
|
||||
|
||||
Output Parameters
|
||||
-----------------
|
||||
|
||||
The output parameters can be declared with the same syntax after the
|
||||
``returns`` keyword. For example, suppose we wished to return two results:
|
||||
the sum and the product of the two given integers, then we would
|
||||
write::
|
||||
|
||||
contract Simple {
|
||||
function arithmetics(uint _a, uint _b) returns (uint o_sum, uint o_product) {
|
||||
o_sum = _a + _b;
|
||||
o_product = _a * _b;
|
||||
}
|
||||
}
|
||||
|
||||
The names of output parameters can be omitted.
|
||||
The output values can also be specified using ``return`` statements.
|
||||
The ``return`` statements are also capable of returning multiple
|
||||
values, see :ref:`multi-return`.
|
||||
Return parameters are initialized to zero; if they are not explicitly
|
||||
set, they stay to be zero.
|
||||
|
||||
Input parameters and output parameters can be used as expressions in
|
||||
the function body. There, they are also usable in the left-hand side
|
||||
of assignment.
|
||||
|
||||
.. index:: if, else, while, do/while, for, break, continue, return, switch, goto
|
||||
|
||||
Control Structures
|
||||
===================
|
||||
|
||||
Most of the control structures from C or JavaScript are available in Solidity
|
||||
Most of the control structures from JavaScript are available in Solidity
|
||||
except for ``switch`` and ``goto``. So
|
||||
there is: ``if``, ``else``, ``while``, ``do``, ``for``, ``break``, ``continue``, ``return``, ``? :``, with
|
||||
the usual semantics known from C or JavaScript.
|
||||
@ -16,7 +66,17 @@ Parentheses can *not* be omitted for conditionals, but curly brances can be omit
|
||||
around single-statement bodies.
|
||||
|
||||
Note that there is no type conversion from non-boolean to boolean types as
|
||||
there is in C and JavaScript, so ``if (1) { ... }`` is *not* valid Solidity.
|
||||
there is in C and JavaScript, so ``if (1) { ... }`` is *not* valid
|
||||
Solidity.
|
||||
|
||||
.. _multi-return:
|
||||
|
||||
Returning Multiple Values
|
||||
-------------------------
|
||||
|
||||
When a function has multiple output parameters, ``return (v0, v1, ...,
|
||||
vn)`` can return multiple values. The number of components must be
|
||||
the same as the number of output parameters.
|
||||
|
||||
.. index:: ! function;call, function;internal, function;external
|
||||
|
||||
@ -322,17 +382,18 @@ In the following example, we show how ``throw`` can be used to easily revert an
|
||||
}
|
||||
}
|
||||
|
||||
Currently, there are situations, where exceptions happen automatically in Solidity:
|
||||
Currently, Solidity automatically generates a runtime exception in the following situations:
|
||||
|
||||
1. If you access an array at a too large or negative index (i.e. ``x[i]`` where ``i >= x.length`` or ``i < 0``).
|
||||
2. If you access a fixed-length ``bytesN`` at a too large or negative index.
|
||||
3. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall`` or ``callcode`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``.
|
||||
4. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly").
|
||||
5. If you divide or modulo by zero (e.g. ``5 / 0`` or ``23 % 0``).
|
||||
6. If you convert a value too big or negative into an enum type.
|
||||
7. If you perform an external function call targeting a contract that contains no code.
|
||||
8. If your contract receives Ether via a public function without ``payable`` modifier (including the constructor and the fallback function).
|
||||
9. If your contract receives Ether via a public accessor function.
|
||||
1. If you access a fixed-length ``bytesN`` at a too large or negative index.
|
||||
1. If you call a function via a message call but it does not finish properly (i.e. it runs out of gas, has no matching function, or throws an exception itself), except when a low level operation ``call``, ``send``, ``delegatecall`` or ``callcode`` is used. The low level operations never throw exceptions but indicate failures by returning ``false``.
|
||||
1. If you create a contract using the ``new`` keyword but the contract creation does not finish properly (see above for the definition of "not finish properly").
|
||||
1. If you divide or modulo by zero (e.g. ``5 / 0`` or ``23 % 0``).
|
||||
1. If you shift by a negative amount.
|
||||
1. If you convert a value too big or negative into an enum type.
|
||||
1. If you perform an external function call targeting a contract that contains no code.
|
||||
1. If your contract receives Ether via a public function without ``payable`` modifier (including the constructor and the fallback function).
|
||||
1. If your contract receives Ether via a public accessor function.
|
||||
|
||||
Internally, Solidity performs an "invalid jump" when an exception is thrown and thus causes the EVM to revert all changes made to the state. The reason for this is that there is no safe way to continue execution, because an expected effect did not occur. Because we want to retain the atomicity of transactions, the safest thing to do is to revert all changes and make the whole transaction (or at least call) without effect.
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -44,6 +44,21 @@ To install it, simply use
|
||||
Details about the usage of the Node.js package can be found in the
|
||||
`solc-js repository <https://github.com/ethereum/solc-js>`_.
|
||||
|
||||
Docker
|
||||
======
|
||||
|
||||
We provide up to date docker builds for the compiler. The ``stable``
|
||||
repository contains released versions while the ``nightly``
|
||||
repository contains potentially unstable changes in the develop branch.
|
||||
|
||||
.. code:: bash
|
||||
|
||||
docker run ethereum/solc:stable solc --version
|
||||
|
||||
Currenty, the docker image only contains the compiler executable,
|
||||
so you have to do some additional work to link in the source and
|
||||
output directories.
|
||||
|
||||
Binary Packages
|
||||
===============
|
||||
|
||||
|
@ -433,7 +433,7 @@ Logs
|
||||
====
|
||||
|
||||
It is possible to store data in a specially indexed data structure
|
||||
that maps all they way up to the block level. This feature called **logs**
|
||||
that maps all the way up to the block level. This feature called **logs**
|
||||
is used by Solidity in order to implement **events**.
|
||||
Contracts cannot access log data after it has been created, but they
|
||||
can be efficiently accessed from outside the blockchain.
|
||||
|
@ -56,6 +56,8 @@ So for the following contract snippet::
|
||||
|
||||
The position of ``data[4][9].b`` is at ``keccak256(uint256(9) . keccak256(uint256(4) . uint256(1))) + 1``.
|
||||
|
||||
.. index: memory layout
|
||||
|
||||
****************
|
||||
Layout in Memory
|
||||
****************
|
||||
@ -72,7 +74,69 @@ Solidity always places new objects at the free memory pointer and memory is neve
|
||||
.. warning::
|
||||
There are some operations in Solidity that need a temporary memory area larger than 64 bytes and therefore will not fit into the scratch space. They will be placed where the free memory points to, but given their short lifecycle, the pointer is not updated. The memory may or may not be zeroed out. Because of this, one shouldn't expect the free memory to be zeroed out.
|
||||
|
||||
.. index: memory layout
|
||||
|
||||
.. index: calldata layout
|
||||
|
||||
*******************
|
||||
Layout of Call Data
|
||||
*******************
|
||||
|
||||
When a Solidity contract is deployed and when it is called from an
|
||||
account, the input data is assumed to be in the format in `the ABI
|
||||
specification
|
||||
<https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI>`_. The
|
||||
ABI specification requires arguments to be padded to multiples of 32
|
||||
bytes. The internal function calls use a different convention.
|
||||
|
||||
|
||||
.. index: variable cleanup
|
||||
|
||||
*********************************
|
||||
Internals - Cleaning Up Variables
|
||||
*********************************
|
||||
|
||||
When a value is shorter than 256-bit, in some cases the remaining bits
|
||||
must be cleaned.
|
||||
The Solidity compiler is designed to clean such remaining bits before any operations
|
||||
that might be adversely affected by the potential garbage in the remaining bits.
|
||||
For example, before writing a value to the memory, the remaining bits need
|
||||
to be cleared because the memory contents can be used for computing
|
||||
hashes or sent as the data of a message call. Similarly, before
|
||||
storing a value in the storage, the remaining bits need to be cleaned
|
||||
because otherwise the garbled value can be observed.
|
||||
|
||||
On the other hand, we do not clean the bits if the immediately
|
||||
following operation is not affected. For instance, since any non-zero
|
||||
value is considered ``true`` by ``JUMPI`` instruction, we do not clean
|
||||
the boolean values before they are used as the condition for
|
||||
``JUMPI``.
|
||||
|
||||
In addition to the design principle above, the Solidity compiler
|
||||
cleans input data when it is loaded onto the stack.
|
||||
|
||||
Different types have different rules for cleaning up invalid values:
|
||||
|
||||
+---------------+---------------+-------------------+
|
||||
|Type |Valid Values |Invalid Values Mean|
|
||||
+===============+===============+===================+
|
||||
|enum of n |0 until n - 1 |exception |
|
||||
|members | | |
|
||||
+---------------+---------------+-------------------+
|
||||
|bool |0 or 1 |1 |
|
||||
+---------------+---------------+-------------------+
|
||||
|signed integers|sign-extended |currently silently |
|
||||
| |word |wraps; in the |
|
||||
| | |future exceptions |
|
||||
| | |will be thrown |
|
||||
| | | |
|
||||
| | | |
|
||||
+---------------+---------------+-------------------+
|
||||
|unsigned |higher bits |currently silently |
|
||||
|integers |zeroed |wraps; in the |
|
||||
| | |future exceptions |
|
||||
| | |will be thrown |
|
||||
+---------------+---------------+-------------------+
|
||||
|
||||
|
||||
*****************
|
||||
Esoteric Features
|
||||
@ -221,6 +285,142 @@ Either add ``--libraries "Math:0x12345678901234567890 Heap:0xabcdef0123456"`` to
|
||||
|
||||
If ``solc`` is called with the option ``--link``, all input files are interpreted to be unlinked binaries (hex-encoded) in the ``__LibraryName____``-format given above and are linked in-place (if the input is read from stdin, it is written to stdout). All options except ``--libraries`` are ignored (including ``-o``) in this case.
|
||||
|
||||
*****************
|
||||
Contract Metadata
|
||||
*****************
|
||||
|
||||
The Solidity compiler automatically generates a JSON file, the
|
||||
contract metadata, that contains information about the current contract.
|
||||
It can be used to query the compiler version, the sources used, the ABI
|
||||
and NatSpec documentation in order to more safely interact with the contract
|
||||
and to verify its source code.
|
||||
|
||||
The compiler appends a Swarm hash of the metadata file to the end of the
|
||||
bytecode (for details, see below) of each contract, so that you can retrieve
|
||||
the file in an authenticated way without having to resort to a centralized
|
||||
data provider.
|
||||
|
||||
Of course, you have to publish the metadata file to Swarm (or some other service)
|
||||
so that others can access it. The file can be output by using ``solc --metadata``
|
||||
and the file will be called ``ContractName_meta.json``.
|
||||
It will contain Swarm references to the source code, so you have to upload
|
||||
all source files and the metadata file.
|
||||
|
||||
The metadata file has the following format. The example below is presented in a
|
||||
human-readable way. Properly formatted metadata should use quotes correctly,
|
||||
reduce whitespace to a minimum and sort the keys of all objects to arrive at a
|
||||
unique formatting.
|
||||
Comments are of course also not permitted and used here only for explanatory purposes.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
{
|
||||
// Required: The version of the metadata format
|
||||
version: "1",
|
||||
// Required: Source code language, basically selects a "sub-version"
|
||||
// of the specification
|
||||
language: "Solidity",
|
||||
// Required: Details about the compiler, contents are specific
|
||||
// to the language.
|
||||
compiler: {
|
||||
// Required for Solidity: Version of the compiler
|
||||
version: "0.4.6+commit.2dabbdf0.Emscripten.clang",
|
||||
// Optional: Hash of the compiler binary which produced this output
|
||||
keccak256: "0x123..."
|
||||
},
|
||||
// Required: Compilation source files/source units, keys are file names
|
||||
sources:
|
||||
{
|
||||
"myFile.sol": {
|
||||
// Required: keccak256 hash of the source file
|
||||
"keccak256": "0x123...",
|
||||
// Required (unless "content" is used, see below): Sorted URL(s)
|
||||
// to the source file, protocol is more or less arbitrary, but a
|
||||
// Swarm URL is recommended
|
||||
"urls": [ "bzzr://56ab..." ]
|
||||
},
|
||||
"mortal": {
|
||||
// Required: keccak256 hash of the source file
|
||||
"keccak256": "0x234...",
|
||||
// Required (unless "url" is used): literal contents of the source file
|
||||
"content": "contract mortal is owned { function kill() { if (msg.sender == owner) selfdestruct(owner); } }"
|
||||
}
|
||||
},
|
||||
// Required: Compiler settings
|
||||
settings:
|
||||
{
|
||||
// Required for Solidity: Sorted list of remappings
|
||||
remappings: [ ":g/dir" ],
|
||||
// Optional: Optimizer settings (enabled defaults to false)
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 500
|
||||
},
|
||||
// Required for Solidity: File and name of the contract or library this
|
||||
// metadata is created for.
|
||||
compilationTarget: {
|
||||
"myFile.sol": "MyContract"
|
||||
},
|
||||
// Required for Solidity: Addresses for libraries used
|
||||
libraries: {
|
||||
"MyLib": "0x123123..."
|
||||
}
|
||||
},
|
||||
// Required: Generated information about the contract.
|
||||
output:
|
||||
{
|
||||
// Required: ABI definition of the contract
|
||||
abi: [ ... ],
|
||||
// Required: NatSpec user documentation of the contract
|
||||
userdoc: [ ... ],
|
||||
// Required: NatSpec developer documentation of the contract
|
||||
devdoc: [ ... ],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Encoding of the Metadata Hash in the Bytecode
|
||||
=============================================
|
||||
|
||||
Because we might support other ways to retrieve the metadata file in the future,
|
||||
the mapping ``{"bzzr0": <Swarm hash>}`` is stored
|
||||
[CBOR](https://tools.ietf.org/html/rfc7049)-encoded. Since the beginning of that
|
||||
encoding is not easy to find, its length is added in a two-byte big-endian
|
||||
encoding. The current version of the Solidity compiler thus adds the following
|
||||
to the end of the deployed bytecode::
|
||||
|
||||
0xa1 0x65 'b' 'z' 'z' 'r' '0' 0x58 0x20 <32 bytes swarm hash> 0x00 0x29
|
||||
|
||||
So in order to retrieve the data, the end of the deployed bytecode can be checked
|
||||
to match that pattern and use the Swarm hash to retrieve the file.
|
||||
|
||||
Usage for Automatic Interface Generation and NatSpec
|
||||
====================================================
|
||||
|
||||
The metadata is used in the following way: A component that wants to interact
|
||||
with a contract (e.g. Mist) retrieves the code of the contract, from that
|
||||
the Swarm hash of a file which is then retrieved.
|
||||
That file is JSON-decoded into a structure like above.
|
||||
|
||||
The component can then use the ABI to automatically generate a rudimentary
|
||||
user interface for the contract.
|
||||
|
||||
Furthermore, Mist can use the userdoc to display a confirmation message to the user
|
||||
whenever they interact with the contract.
|
||||
|
||||
Usage for Source Code Verification
|
||||
==================================
|
||||
|
||||
In order to verify the compilation, sources can be retrieved from Swarm
|
||||
via the link in the metadata file.
|
||||
The compiler of the correct version (which is checked to be part of the "official" compilers)
|
||||
is invoked on that input with the specified settings. The resulting
|
||||
bytecode is compared to the data of the creation transaction or CREATE opcode data.
|
||||
This automatically verifies the metadata since its hash is part of the bytecode.
|
||||
Excess data corresponds to the constructor input data, which should be decoded
|
||||
according to the interface and presented to the user.
|
||||
|
||||
|
||||
***************
|
||||
Tips and Tricks
|
||||
***************
|
||||
@ -363,10 +563,10 @@ Reserved Keywords
|
||||
|
||||
These keywords are reserved in Solidity. They might become part of the syntax in the future:
|
||||
|
||||
``abstract``, ``after``, ``case``, ``catch``, ``final``, ``in``, ``inline``, ``interface``, ``let``, ``match``,
|
||||
``abstract``, ``after``, ``case``, ``catch``, ``default``, ``final``, ``in``, ``inline``, ``interface``, ``let``, ``match``, ``null``,
|
||||
``of``, ``pure``, ``relocatable``, ``static``, ``switch``, ``try``, ``type``, ``typeof``, ``view``.
|
||||
|
||||
Language Grammar
|
||||
================
|
||||
|
||||
The entire language grammar is `available here <https://github.com/ethereum/solidity/blob/release/libsolidity/grammar.txt>`_.
|
||||
.. literalinclude:: grammar.txt
|
||||
|
@ -150,6 +150,74 @@ No::
|
||||
...
|
||||
}
|
||||
|
||||
Order of Functions
|
||||
==================
|
||||
|
||||
Ordering helps readers identify which functions they can call and to find the constructor and fallback definitions easier.
|
||||
|
||||
Functions should be grouped according to their visibility and ordered:
|
||||
|
||||
- constructor
|
||||
- fallback function (if exists)
|
||||
- external
|
||||
- public
|
||||
- internal
|
||||
- private
|
||||
|
||||
Within a grouping, place the `constant` functions last.
|
||||
|
||||
Yes::
|
||||
|
||||
contract A {
|
||||
function A() {
|
||||
...
|
||||
}
|
||||
|
||||
function() {
|
||||
...
|
||||
}
|
||||
|
||||
// External functions
|
||||
// ...
|
||||
|
||||
// External functions that are constant
|
||||
// ...
|
||||
|
||||
// Public functions
|
||||
// ...
|
||||
|
||||
// Internal functions
|
||||
// ...
|
||||
|
||||
// Private functions
|
||||
// ...
|
||||
}
|
||||
|
||||
No::
|
||||
|
||||
contract A {
|
||||
|
||||
// External functions
|
||||
// ...
|
||||
|
||||
// Private functions
|
||||
// ...
|
||||
|
||||
// Public functions
|
||||
// ...
|
||||
|
||||
function A() {
|
||||
...
|
||||
}
|
||||
|
||||
function() {
|
||||
...
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
// ...
|
||||
}
|
||||
|
||||
Whitespace in Expressions
|
||||
=========================
|
||||
|
||||
@ -194,6 +262,19 @@ No::
|
||||
y = 2;
|
||||
long_variable = 3;
|
||||
|
||||
Don't include a whitespace in the fallback function:
|
||||
|
||||
Yes::
|
||||
|
||||
function() {
|
||||
...
|
||||
}
|
||||
|
||||
No::
|
||||
|
||||
function () {
|
||||
...
|
||||
}
|
||||
|
||||
Control Structures
|
||||
==================
|
||||
|
@ -52,12 +52,17 @@ Operators:
|
||||
|
||||
* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)
|
||||
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
|
||||
* Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation)
|
||||
* Arithmetic operators: ``+``, ``-``, unary ``-``, unary ``+``, ``*``, ``/``, ``%`` (remainder), ``**`` (exponentiation), ``<<`` (left shift), ``>>`` (right shift)
|
||||
|
||||
Division always truncates (it just maps to the DIV opcode of the EVM), but it does not truncate if both
|
||||
operators are :ref:`literals<rational_literals>` (or literal expressions).
|
||||
|
||||
Division by zero and modulus with zero throws an exception.
|
||||
Division by zero and modulus with zero throws a runtime exception.
|
||||
|
||||
The result of a shift operation is the type of the left operand. The
|
||||
expression ``x << y`` is equivalent to ``x * 2**y`` and ``x >> y`` is
|
||||
equivalent to ``x / 2**y``. This means that shifting negative numbers
|
||||
sign extends. Shifting by a negative amount throws a runtime exception.
|
||||
|
||||
.. index:: address, balance, send, call, callcode, delegatecall
|
||||
|
||||
@ -136,9 +141,13 @@ Fixed-size byte arrays
|
||||
Operators:
|
||||
|
||||
* Comparisons: ``<=``, ``<``, ``==``, ``!=``, ``>=``, ``>`` (evaluate to ``bool``)
|
||||
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation)
|
||||
* Bit operators: ``&``, ``|``, ``^`` (bitwise exclusive or), ``~`` (bitwise negation), ``<<`` (left shift), ``>>`` (right shift)
|
||||
* Index access: If ``x`` is of type ``bytesI``, then ``x[k]`` for ``0 <= k < I`` returns the ``k`` th byte (read-only).
|
||||
|
||||
The shifting operator works with any integer type as right operand (but will
|
||||
return the type of the left operand), which denotes the number of bits to shift by.
|
||||
Shifting by a negative amount will cause a runtime exception.
|
||||
|
||||
Members:
|
||||
|
||||
* ``.length`` yields the fixed length of the byte array (read-only).
|
||||
@ -169,9 +178,18 @@ Fixed Point Numbers
|
||||
Rational and Integer Literals
|
||||
-----------------------------
|
||||
|
||||
All number literals retain arbitrary precision until they are converted to a non-literal type (i.e. by
|
||||
using them together with a non-literal type). This means that computations do not overflow but also
|
||||
divisions do not truncate.
|
||||
Integer literals are formed from a sequence of numbers in the range 0-9.
|
||||
They are interpreted as decimals. For example, ``69`` means sixty nine.
|
||||
Octal literals do not exist in Solidity and leading zeros are ignored.
|
||||
For example, ``0100`` means one hundred.
|
||||
|
||||
Decimal literals are formed by a ``.`` with at least one number on
|
||||
one side. Examples include ``1.``, ``.1`` and ``1.3``.
|
||||
|
||||
Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by
|
||||
using them together with a non-literal expression).
|
||||
This means that computations do not overflow and divisions do not truncate
|
||||
in number literal expressions.
|
||||
|
||||
For example, ``(2**800 + 1) - 2**800`` results in the constant ``1`` (of type ``uint8``)
|
||||
although intermediate results would not even fit the machine word size. Furthermore, ``.5 * 8`` results
|
||||
@ -185,11 +203,19 @@ In ``var x = 1/4;``, ``x`` will receive the type ``ufixed0x8`` while in ``var x
|
||||
the type ``ufixed0x256`` because ``1/3`` is not finitely representable in binary and will thus be
|
||||
approximated.
|
||||
|
||||
Any operator that can be applied to integers can also be applied to literal expressions as
|
||||
Any operator that can be applied to integers can also be applied to number literal expressions as
|
||||
long as the operands are integers. If any of the two is fractional, bit operations are disallowed
|
||||
and exponentiation is disallowed if the exponent is fractional (because that might result in
|
||||
a non-rational number).
|
||||
|
||||
.. note::
|
||||
Solidity has a number literal type for each rational number.
|
||||
Integer literals and rational number literals belong to number literal types.
|
||||
Moreover, all number literal expressions (i.e. the expressions that
|
||||
contain only number literals and operators) belong to number literal
|
||||
types. So the number literal expressions `1 + 2` and `2 + 1` both
|
||||
belong to the same number literal type for the rational number three.
|
||||
|
||||
.. note::
|
||||
Most finite decimal fractions like ``5.3743`` are not finitely representable in binary. The correct type
|
||||
for ``5.3743`` is ``ufixed8x248`` because that allows to best approximate the number. If you want to
|
||||
@ -200,7 +226,7 @@ a non-rational number).
|
||||
Division on integer literals used to truncate in earlier versions, but it will now convert into a rational number, i.e. ``5 / 2`` is not equal to ``2``, but to ``2.5``.
|
||||
|
||||
.. note::
|
||||
Literal expressions are converted to a permanent type as soon as they are used with other
|
||||
Number literal expressions are converted into a non-literal type as soon as they are used with non-literal
|
||||
expressions. Even though we know that the value of the
|
||||
expression assigned to ``b`` in the following example evaluates to an integer, it still
|
||||
uses fixed point types (and not rational number literals) in between and so the code
|
||||
@ -216,7 +242,7 @@ a non-rational number).
|
||||
String Literals
|
||||
---------------
|
||||
|
||||
String literals are written with either double or single-quotes (``"foo"`` or ``'bar'``). As with integer literals, their type can vary, but they are implicitly convertible to ``bytes1``, ..., ``bytes32``, if they fit, to ``bytes`` and to ``string``.
|
||||
String literals are written with either double or single-quotes (``"foo"`` or ``'bar'``). They do not imply trailing zeroes as in C; `"foo"`` represents three bytes not four. As with integer literals, their type can vary, but they are implicitly convertible to ``bytes1``, ..., ``bytes32``, if they fit, to ``bytes`` and to ``string``.
|
||||
|
||||
String literals support escape characters, such as ``\n``, ``\xNN`` and ``\uNNNN``. ``\xNN`` takes a hex value and inserts the appropriate byte, while ``\uNNNN`` takes a Unicode codepoint and inserts an UTF-8 sequence.
|
||||
|
||||
@ -312,12 +338,19 @@ If external function types are used outside of the context of Solidity,
|
||||
they are treated as the ``function`` type, which encodes the address
|
||||
followed by the function identifier together in a single ``bytes24`` type.
|
||||
|
||||
Note that public functions of the current contract can be used both as an
|
||||
internal and as an external function. To use ``f`` as an internal function,
|
||||
just use ``f``, if you want to use its external form, use ``this.f``.
|
||||
|
||||
Example that shows how to use internal function types::
|
||||
|
||||
pragma solidity ^0.4.5;
|
||||
|
||||
library ArrayUtils {
|
||||
// internal functions can be used in internal library functions because
|
||||
// they will be part of the same code context
|
||||
function map(uint[] memory self, function (uint) returns (uint) f)
|
||||
internal
|
||||
returns (uint[] memory r)
|
||||
{
|
||||
r = new uint[](self.length);
|
||||
@ -327,8 +360,9 @@ Example that shows how to use internal function types::
|
||||
}
|
||||
function reduce(
|
||||
uint[] memory self,
|
||||
function (uint) returns (uint) f
|
||||
function (uint x, uint y) returns (uint) f
|
||||
)
|
||||
internal
|
||||
returns (uint r)
|
||||
{
|
||||
r = self[0];
|
||||
@ -336,7 +370,7 @@ Example that shows how to use internal function types::
|
||||
r = f(r, self[i]);
|
||||
}
|
||||
}
|
||||
function range(uint length) returns (uint[] memory r) {
|
||||
function range(uint length) internal returns (uint[] memory r) {
|
||||
r = new uint[](length);
|
||||
for (uint i = 0; i < r.length; i++) {
|
||||
r[i] = i;
|
||||
@ -346,7 +380,7 @@ Example that shows how to use internal function types::
|
||||
|
||||
contract Pyramid {
|
||||
using ArrayUtils for *;
|
||||
function pyramid(uint l) return (uint) {
|
||||
function pyramid(uint l) returns (uint) {
|
||||
return ArrayUtils.range(l).map(square).reduce(sum);
|
||||
}
|
||||
function square(uint x) internal returns (uint) {
|
||||
@ -359,14 +393,16 @@ Example that shows how to use internal function types::
|
||||
|
||||
Another example that uses external function types::
|
||||
|
||||
pragma solidity ^0.4.5;
|
||||
|
||||
contract Oracle {
|
||||
struct Request {
|
||||
bytes data;
|
||||
function(bytes) external callback;
|
||||
function(bytes memory) external callback;
|
||||
}
|
||||
Request[] requests;
|
||||
event NewRequest(uint);
|
||||
function query(bytes data, function(bytes) external callback) {
|
||||
function query(bytes data, function(bytes memory) external callback) {
|
||||
requests.push(Request(data, callback));
|
||||
NewRequest(requests.length - 1);
|
||||
}
|
||||
@ -377,12 +413,12 @@ Another example that uses external function types::
|
||||
}
|
||||
|
||||
contract OracleUser {
|
||||
Oracle constant oracle = 0x1234567; // known contract
|
||||
Oracle constant oracle = Oracle(0x1234567); // known contract
|
||||
function buySomething() {
|
||||
oracle.query("USD", oracleResponse);
|
||||
oracle.query("USD", this.oracleResponse);
|
||||
}
|
||||
function oracleResponse(bytes response) {
|
||||
if (msg.sender != oracle) throw;
|
||||
if (msg.sender != address(oracle)) throw;
|
||||
// Use the data
|
||||
}
|
||||
}
|
||||
@ -729,9 +765,9 @@ assigning it to a local variable, as in
|
||||
Mappings
|
||||
========
|
||||
|
||||
Mapping types are declared as ``mapping _KeyType => _ValueType``, where
|
||||
``_KeyType`` can be almost any type except for a mapping and ``_ValueType``
|
||||
can actually be any type, including mappings.
|
||||
Mapping types are declared as ``mapping _KeyType => _ValueType``.
|
||||
Here ``_KeyType`` can be almost any type except for a mapping, a dynamically sized array, a contract, an enum and a struct.
|
||||
``_ValueType`` can actually be any type, including mappings.
|
||||
|
||||
Mappings can be seen as hashtables which are virtually initialized such that
|
||||
every possible key exists and is mapped to a value whose byte-representation is
|
||||
|
@ -135,6 +135,17 @@ inline u256 s2u(s256 _u)
|
||||
return u256(c_end + _u);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& os, bytes const& _bytes)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << std::hex;
|
||||
std::copy(_bytes.begin(), _bytes.end(), std::ostream_iterator<int>(ss, ","));
|
||||
std::string result = ss.str();
|
||||
result.pop_back();
|
||||
os << "[" + result + "]";
|
||||
return os;
|
||||
}
|
||||
|
||||
template <size_t n> inline u256 exp10()
|
||||
{
|
||||
return exp10<n - 1>() * u256(10);
|
||||
|
@ -27,14 +27,14 @@
|
||||
namespace dev
|
||||
{
|
||||
|
||||
/// Serialise the JSON object (@a _input) with identation
|
||||
std::string jsonPrettyPrint(Json::Value const& _input)
|
||||
/// Serialise the JSON object (@a _input) with indentation
|
||||
inline std::string jsonPrettyPrint(Json::Value const& _input)
|
||||
{
|
||||
return Json::StyledWriter().write(_input);
|
||||
}
|
||||
|
||||
/// Serialise theJ SON object (@a _input) without identation
|
||||
std::string jsonCompactPrint(Json::Value const& _input)
|
||||
/// Serialise the JSON object (@a _input) without indentation
|
||||
inline std::string jsonCompactPrint(Json::Value const& _input)
|
||||
{
|
||||
Json::FastWriter writer;
|
||||
writer.omitEndingLineFeed();
|
||||
|
@ -38,13 +38,14 @@ h256 swarmHashSimple(bytesConstRef _data, size_t _size)
|
||||
return keccak256(toLittleEndian(_size) + _data.toBytes());
|
||||
}
|
||||
|
||||
h256 swarmHashIntermediate(bytes const& _input, size_t _offset, size_t _length)
|
||||
h256 swarmHashIntermediate(string const& _input, size_t _offset, size_t _length)
|
||||
{
|
||||
bytesConstRef ref;
|
||||
bytes innerNodes;
|
||||
if (_length <= 0x1000)
|
||||
return swarmHashSimple(bytesConstRef(_input.data() + _offset, _length), _length);
|
||||
ref = bytesConstRef(_input).cropped(_offset, _length);
|
||||
else
|
||||
{
|
||||
bytes innerNodes;
|
||||
size_t maxRepresentedSize = 0x1000;
|
||||
while (maxRepresentedSize * (0x1000 / 32) < _length)
|
||||
maxRepresentedSize *= (0x1000 / 32);
|
||||
@ -53,11 +54,12 @@ h256 swarmHashIntermediate(bytes const& _input, size_t _offset, size_t _length)
|
||||
size_t size = std::min(maxRepresentedSize, _length - i);
|
||||
innerNodes += swarmHashIntermediate(_input, _offset + i, size).asBytes();
|
||||
}
|
||||
return swarmHashSimple(bytesConstRef(&innerNodes), _length);
|
||||
ref = bytesConstRef(&innerNodes);
|
||||
}
|
||||
return swarmHashSimple(ref, _length);
|
||||
}
|
||||
|
||||
h256 dev::swarmHash(bytes const& _input)
|
||||
h256 dev::swarmHash(string const& _input)
|
||||
{
|
||||
return swarmHashIntermediate(_input, 0, _input.size());
|
||||
}
|
||||
|
@ -20,12 +20,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <libdevcore/FixedHash.h>
|
||||
#include <libdevcore/Common.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
|
||||
/// Compute the "swarm hash" of @a _data
|
||||
h256 swarmHash(bytes const& _data);
|
||||
h256 swarmHash(std::string const& _data);
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace dev
|
||||
{
|
||||
|
||||
|
||||
bool validate(std::string const& _input, size_t& _invalidPosition)
|
||||
bool validateUTF8(std::string const& _input, size_t& _invalidPosition)
|
||||
{
|
||||
const size_t length = _input.length();
|
||||
bool valid = true;
|
||||
|
@ -29,7 +29,13 @@ namespace dev
|
||||
{
|
||||
|
||||
/// Validate an input for UTF8 encoding
|
||||
/// @returns true if it is invalid and the first invalid position in invalidPosition
|
||||
bool validate(std::string const& _input, size_t& _invalidPosition);
|
||||
/// @returns false if it is invalid and the first invalid position in invalidPosition
|
||||
bool validateUTF8(std::string const& _input, size_t& _invalidPosition);
|
||||
|
||||
inline bool validateUTF8(std::string const& _input)
|
||||
{
|
||||
size_t invalidPos;
|
||||
return validateUTF8(_input, invalidPos);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Assembly.cpp
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
@ -331,13 +331,12 @@ map<u256, u256> Assembly::optimiseInternal(bool _enable, bool _isCreation, size_
|
||||
}
|
||||
|
||||
map<u256, u256> tagReplacements;
|
||||
unsigned total = 0;
|
||||
for (unsigned count = 1; count > 0; total += count)
|
||||
for (unsigned count = 1; count > 0;)
|
||||
{
|
||||
count = 0;
|
||||
|
||||
PeepholeOptimiser peepOpt(m_items);
|
||||
if (peepOpt.optimise())
|
||||
while (peepOpt.optimise())
|
||||
count++;
|
||||
|
||||
if (!_enable)
|
||||
@ -399,7 +398,7 @@ map<u256, u256> Assembly::optimiseInternal(bool _enable, bool _isCreation, size_
|
||||
}
|
||||
|
||||
if (_enable)
|
||||
total += ConstantOptimisationMethod::optimiseConstants(
|
||||
ConstantOptimisationMethod::optimiseConstants(
|
||||
_isCreation,
|
||||
_isCreation ? 1 : _runs,
|
||||
*this,
|
||||
@ -433,7 +432,7 @@ LinkerObject const& Assembly::assemble() const
|
||||
unsigned bytesPerTag = dev::bytesRequired(bytesRequiredForCode);
|
||||
byte tagPush = (byte)Instruction::PUSH1 - 1 + bytesPerTag;
|
||||
|
||||
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1;
|
||||
unsigned bytesRequiredIncludingData = bytesRequiredForCode + 1 + m_auxiliaryData.size();
|
||||
for (auto const& sub: m_subs)
|
||||
bytesRequiredIncludingData += sub->assemble().bytecode.size();
|
||||
|
||||
@ -526,8 +525,10 @@ LinkerObject const& Assembly::assemble() const
|
||||
}
|
||||
}
|
||||
|
||||
if (!dataRef.empty() && !subRef.empty())
|
||||
if (!m_subs.empty() || !m_data.empty() || !m_auxiliaryData.empty())
|
||||
// Append a STOP just to be sure.
|
||||
ret.bytecode.push_back(0);
|
||||
|
||||
for (size_t i = 0; i < m_subs.size(); ++i)
|
||||
{
|
||||
auto references = subRef.equal_range(i);
|
||||
@ -569,6 +570,9 @@ LinkerObject const& Assembly::assemble() const
|
||||
}
|
||||
ret.bytecode += dataItem.second;
|
||||
}
|
||||
|
||||
ret.bytecode += m_auxiliaryData;
|
||||
|
||||
for (unsigned pos: sizeRef)
|
||||
{
|
||||
bytesRef r(ret.bytecode.data() + pos, bytesPerDataRef);
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@ -71,6 +71,9 @@ public:
|
||||
AssemblyItem appendJumpI(AssemblyItem const& _tag) { auto ret = append(_tag.pushTag()); append(solidity::Instruction::JUMPI); return ret; }
|
||||
AssemblyItem errorTag() { return AssemblyItem(PushTag, 0); }
|
||||
|
||||
/// Appends @a _data literally to the very end of the bytecode.
|
||||
void appendAuxiliaryDataToEnd(bytes const& _data) { m_auxiliaryData += _data; }
|
||||
|
||||
template <class T> Assembly& operator<<(T const& _d) { append(_d); return *this; }
|
||||
AssemblyItems const& items() const { return m_items; }
|
||||
AssemblyItem const& back() const { return m_items.back(); }
|
||||
@ -125,10 +128,12 @@ private:
|
||||
Json::Value createJsonValue(std::string _name, int _begin, int _end, std::string _value = std::string(), std::string _jumpType = std::string()) const;
|
||||
|
||||
protected:
|
||||
// 0 is reserved for exception
|
||||
/// 0 is reserved for exception
|
||||
unsigned m_usedTags = 1;
|
||||
AssemblyItems m_items;
|
||||
std::map<h256, bytes> m_data;
|
||||
/// Data that is appended to the very end of the contract.
|
||||
bytes m_auxiliaryData;
|
||||
std::vector<std::shared_ptr<Assembly>> m_subs;
|
||||
std::map<h256, std::string> m_strings;
|
||||
std::map<h256, std::string> m_libraries; ///< Identifiers of libraries to be linked.
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Assembly.cpp
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
|
@ -1,20 +1,20 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Assembly.h
|
||||
/** @file AssemblyItem.h
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
* @date 2014
|
||||
*/
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file BlockDeduplicator.cpp
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file BlockDeduplicator.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file CommonSubexpressionEliminator.cpp
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file CommonSubexpressionEliminator.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file ConstantOptimiser.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file ConstantOptimiser.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ControlFlowGraph.cpp
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ControlFlowGraph.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file EVMSchedule.h
|
||||
* @author Gav <i@gavwood.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Exceptions.h
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ExpressionClasses.cpp
|
||||
@ -245,22 +245,25 @@ Rules::Rules()
|
||||
|
||||
// invariants involving known constants
|
||||
{{Instruction::ADD, {X, 0}}, [=]{ return X; }},
|
||||
{{Instruction::SUB, {X, 0}}, [=]{ return X; }},
|
||||
{{Instruction::MUL, {X, 1}}, [=]{ return X; }},
|
||||
{{Instruction::DIV, {X, 1}}, [=]{ return X; }},
|
||||
{{Instruction::SDIV, {X, 1}}, [=]{ return X; }},
|
||||
{{Instruction::OR, {X, 0}}, [=]{ return X; }},
|
||||
{{Instruction::XOR, {X, 0}}, [=]{ return X; }},
|
||||
{{Instruction::AND, {X, ~u256(0)}}, [=]{ return X; }},
|
||||
{{Instruction::AND, {X, 0}}, [=]{ return u256(0); }},
|
||||
{{Instruction::MUL, {X, 0}}, [=]{ return u256(0); }},
|
||||
{{Instruction::DIV, {X, 0}}, [=]{ return u256(0); }},
|
||||
{{Instruction::DIV, {0, X}}, [=]{ return u256(0); }},
|
||||
{{Instruction::MOD, {X, 0}}, [=]{ return u256(0); }},
|
||||
{{Instruction::MOD, {0, X}}, [=]{ return u256(0); }},
|
||||
{{Instruction::AND, {X, 0}}, [=]{ return u256(0); }},
|
||||
{{Instruction::OR, {X, ~u256(0)}}, [=]{ return ~u256(0); }},
|
||||
{{Instruction::EQ, {X, 0}}, [=]() -> Pattern { return {Instruction::ISZERO, {X}}; } },
|
||||
// operations involving an expression and itself
|
||||
{{Instruction::AND, {X, X}}, [=]{ return X; }},
|
||||
{{Instruction::OR, {X, X}}, [=]{ return X; }},
|
||||
{{Instruction::XOR, {X, X}}, [=]{ return u256(0); }},
|
||||
{{Instruction::SUB, {X, X}}, [=]{ return u256(0); }},
|
||||
{{Instruction::EQ, {X, X}}, [=]{ return u256(1); }},
|
||||
{{Instruction::LT, {X, X}}, [=]{ return u256(0); }},
|
||||
@ -270,6 +273,11 @@ Rules::Rules()
|
||||
{{Instruction::MOD, {X, X}}, [=]{ return u256(0); }},
|
||||
|
||||
{{Instruction::NOT, {{Instruction::NOT, {X}}}}, [=]{ return X; }},
|
||||
{{Instruction::XOR, {{{X}, {Instruction::XOR, {X, Y}}}}}, [=]{ return Y; }},
|
||||
{{Instruction::OR, {{{X}, {Instruction::AND, {X, Y}}}}}, [=]{ return X; }},
|
||||
{{Instruction::AND, {{{X}, {Instruction::OR, {X, Y}}}}}, [=]{ return X; }},
|
||||
{{Instruction::AND, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return u256(0); }},
|
||||
{{Instruction::OR, {{{X}, {Instruction::NOT, {X}}}}}, [=]{ return ~u256(0); }},
|
||||
};
|
||||
// Double negation of opcodes with binary result
|
||||
for (auto const& op: vector<Instruction>{
|
||||
@ -287,6 +295,10 @@ Rules::Rules()
|
||||
{Instruction::ISZERO, {{Instruction::ISZERO, {{Instruction::ISZERO, {X}}}}}},
|
||||
[=]() -> Pattern { return {Instruction::ISZERO, {X}}; }
|
||||
});
|
||||
m_rules.push_back({
|
||||
{Instruction::ISZERO, {{Instruction::XOR, {X, Y}}}},
|
||||
[=]() -> Pattern { return { Instruction::EQ, {X, Y} }; }
|
||||
});
|
||||
// Associative operations
|
||||
for (auto const& opFun: vector<pair<Instruction,function<u256(u256 const&,u256 const&)>>>{
|
||||
{Instruction::ADD, plus<u256>()},
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file ExpressionClasses.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file GasMeter.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file GasMeter.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Instruction.cpp
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Instruction.h
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file KnownState.cpp
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file KnownState.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file LinkerObject.cpp
|
||||
* @author Christian R <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file Assembly.h
|
||||
* @author Gav Wood <i@gavwood.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file PathGasMeter.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/** @file PathGasMeter.cpp
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,21 +1,21 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file PeepholeOptimiser.h
|
||||
* @file PeepholeOptimiser.cpp
|
||||
* Performs local optimising code changes to assembly.
|
||||
*/
|
||||
|
||||
@ -30,87 +30,6 @@ using namespace dev;
|
||||
|
||||
// TODO: Extend this to use the tools from ExpressionClasses.cpp
|
||||
|
||||
struct Identity
|
||||
{
|
||||
static size_t windowSize() { return 1; }
|
||||
static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
*_out = *_in;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct PushPop
|
||||
{
|
||||
static size_t windowSize() { return 2; }
|
||||
static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems>)
|
||||
{
|
||||
auto t = _in[0].type();
|
||||
if (_in[1] == Instruction::POP && (
|
||||
SemanticInformation::isDupInstruction(_in[0]) ||
|
||||
t == Push || t == PushString || t == PushTag || t == PushSub ||
|
||||
t == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress
|
||||
))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct DoubleSwap
|
||||
{
|
||||
static size_t windowSize() { return 2; }
|
||||
static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems>)
|
||||
{
|
||||
if (_in[0] == _in[1] && SemanticInformation::isSwapInstruction(_in[0]))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct JumpToNext
|
||||
{
|
||||
static size_t windowSize() { return 3; }
|
||||
static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
if (
|
||||
_in[0].type() == PushTag &&
|
||||
(_in[1] == Instruction::JUMP || _in[1] == Instruction::JUMPI) &&
|
||||
_in[2].type() == Tag &&
|
||||
_in[0].data() == _in[2].data()
|
||||
)
|
||||
{
|
||||
if (_in[1] == Instruction::JUMPI)
|
||||
*_out = AssemblyItem(Instruction::POP, _in[1].location());
|
||||
*_out = _in[2];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct TagConjunctions
|
||||
{
|
||||
static size_t windowSize() { return 3; }
|
||||
static bool apply(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
if (
|
||||
_in[0].type() == PushTag &&
|
||||
_in[2] == Instruction::AND &&
|
||||
_in[1].type() == Push &&
|
||||
(_in[1].data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF)
|
||||
)
|
||||
{
|
||||
*_out = _in[0];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct OptimiserState
|
||||
{
|
||||
AssemblyItems const& items;
|
||||
@ -118,6 +37,186 @@ struct OptimiserState
|
||||
std::back_insert_iterator<AssemblyItems> out;
|
||||
};
|
||||
|
||||
template <class Method, size_t Arguments>
|
||||
struct ApplyRule
|
||||
{
|
||||
};
|
||||
template <class Method>
|
||||
struct ApplyRule<Method, 3>
|
||||
{
|
||||
static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
return Method::applySimple(_in[0], _in[1], _in[2], _out);
|
||||
}
|
||||
};
|
||||
template <class Method>
|
||||
struct ApplyRule<Method, 2>
|
||||
{
|
||||
static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
return Method::applySimple(_in[0], _in[1], _out);
|
||||
}
|
||||
};
|
||||
template <class Method>
|
||||
struct ApplyRule<Method, 1>
|
||||
{
|
||||
static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
return Method::applySimple(_in[0], _out);
|
||||
}
|
||||
};
|
||||
|
||||
template <class Method, size_t WindowSize>
|
||||
struct SimplePeepholeOptimizerMethod
|
||||
{
|
||||
static bool apply(OptimiserState& _state)
|
||||
{
|
||||
if (
|
||||
_state.i + WindowSize <= _state.items.size() &&
|
||||
ApplyRule<Method, WindowSize>::applyRule(_state.items.begin() + _state.i, _state.out)
|
||||
)
|
||||
{
|
||||
_state.i += WindowSize;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct Identity: SimplePeepholeOptimizerMethod<Identity, 1>
|
||||
{
|
||||
static bool applySimple(AssemblyItem const& _item, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
*_out = _item;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct PushPop: SimplePeepholeOptimizerMethod<PushPop, 2>
|
||||
{
|
||||
static bool applySimple(AssemblyItem const& _push, AssemblyItem const& _pop, std::back_insert_iterator<AssemblyItems>)
|
||||
{
|
||||
auto t = _push.type();
|
||||
return _pop == Instruction::POP && (
|
||||
SemanticInformation::isDupInstruction(_push) ||
|
||||
t == Push || t == PushString || t == PushTag || t == PushSub ||
|
||||
t == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct OpPop: SimplePeepholeOptimizerMethod<OpPop, 2>
|
||||
{
|
||||
static bool applySimple(
|
||||
AssemblyItem const& _op,
|
||||
AssemblyItem const& _pop,
|
||||
std::back_insert_iterator<AssemblyItems> _out
|
||||
)
|
||||
{
|
||||
if (_pop == Instruction::POP && _op.type() == Operation)
|
||||
{
|
||||
Instruction instr = _op.instruction();
|
||||
if (instructionInfo(instr).ret == 1 && !instructionInfo(instr).sideEffects)
|
||||
{
|
||||
for (int j = 0; j < instructionInfo(instr).args; j++)
|
||||
*_out = Instruction::POP;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct DoubleSwap: SimplePeepholeOptimizerMethod<DoubleSwap, 2>
|
||||
{
|
||||
static size_t applySimple(AssemblyItem const& _s1, AssemblyItem const& _s2, std::back_insert_iterator<AssemblyItems>)
|
||||
{
|
||||
return _s1 == _s2 && SemanticInformation::isSwapInstruction(_s1);
|
||||
}
|
||||
};
|
||||
|
||||
struct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext, 3>
|
||||
{
|
||||
static size_t applySimple(
|
||||
AssemblyItem const& _pushTag,
|
||||
AssemblyItem const& _jump,
|
||||
AssemblyItem const& _tag,
|
||||
std::back_insert_iterator<AssemblyItems> _out
|
||||
)
|
||||
{
|
||||
if (
|
||||
_pushTag.type() == PushTag &&
|
||||
(_jump == Instruction::JUMP || _jump == Instruction::JUMPI) &&
|
||||
_tag.type() == Tag &&
|
||||
_pushTag.data() == _tag.data()
|
||||
)
|
||||
{
|
||||
if (_jump == Instruction::JUMPI)
|
||||
*_out = AssemblyItem(Instruction::POP, _jump.location());
|
||||
*_out = _tag;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions, 3>
|
||||
{
|
||||
static bool applySimple(
|
||||
AssemblyItem const& _pushTag,
|
||||
AssemblyItem const& _pushConstant,
|
||||
AssemblyItem const& _and,
|
||||
std::back_insert_iterator<AssemblyItems> _out
|
||||
)
|
||||
{
|
||||
if (
|
||||
_pushTag.type() == PushTag &&
|
||||
_and == Instruction::AND &&
|
||||
_pushConstant.type() == Push &&
|
||||
(_pushConstant.data() & u256(0xFFFFFFFF)) == u256(0xFFFFFFFF)
|
||||
)
|
||||
{
|
||||
*_out = _pushTag;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/// Removes everything after a JUMP (or similar) until the next JUMPDEST.
|
||||
struct UnreachableCode
|
||||
{
|
||||
static bool apply(OptimiserState& _state)
|
||||
{
|
||||
auto it = _state.items.begin() + _state.i;
|
||||
auto end = _state.items.end();
|
||||
if (it == end)
|
||||
return false;
|
||||
if (
|
||||
it[0] != Instruction::JUMP &&
|
||||
it[0] != Instruction::RETURN &&
|
||||
it[0] != Instruction::STOP &&
|
||||
it[0] != Instruction::SUICIDE
|
||||
)
|
||||
return false;
|
||||
|
||||
size_t i = 1;
|
||||
while (it + i != end && it[i].type() != Tag)
|
||||
i++;
|
||||
if (i > 1)
|
||||
{
|
||||
*_state.out = it[0];
|
||||
_state.i += i;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
void applyMethods(OptimiserState&)
|
||||
{
|
||||
assertThrow(false, OptimizerException, "Peephole optimizer failed to apply identity.");
|
||||
@ -126,9 +225,7 @@ void applyMethods(OptimiserState&)
|
||||
template <typename Method, typename... OtherMethods>
|
||||
void applyMethods(OptimiserState& _state, Method, OtherMethods... _other)
|
||||
{
|
||||
if (_state.i + Method::windowSize() <= _state.items.size() && Method::apply(_state.items.begin() + _state.i, _state.out))
|
||||
_state.i += Method::windowSize();
|
||||
else
|
||||
if (!Method::apply(_state))
|
||||
applyMethods(_state, _other...);
|
||||
}
|
||||
|
||||
@ -136,7 +233,7 @@ bool PeepholeOptimiser::optimise()
|
||||
{
|
||||
OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)};
|
||||
while (state.i < m_items.size())
|
||||
applyMethods(state, PushPop(), DoubleSwap(), JumpToNext(), TagConjunctions(), Identity());
|
||||
applyMethods(state, PushPop(), OpPop(), DoubleSwap(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity());
|
||||
if (m_optimisedItems.size() < m_items.size())
|
||||
{
|
||||
m_items = std::move(m_optimisedItems);
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file PeepholeOptimiser.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file SemanticInformation.cpp
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @file SemanticInformation.h
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Lefteris Karapetsas <lefteris@ethdev.com>
|
||||
|
@ -91,15 +91,11 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
|
||||
{
|
||||
auto it = _s.vars.find(s);
|
||||
if (it == _s.vars.end())
|
||||
{
|
||||
bool ok;
|
||||
tie(it, ok) = _s.vars.insert(make_pair(s, make_pair(_s.stackSize, 32)));
|
||||
_s.stackSize += 32;
|
||||
}
|
||||
error<InvalidName>(std::string("Symbol not found: ") + s);
|
||||
m_asm.append((u256)it->second.first);
|
||||
}
|
||||
else
|
||||
error<BareSymbol>();
|
||||
error<BareSymbol>(s);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -111,7 +107,9 @@ CodeFragment::CodeFragment(sp::utree const& _t, CompilerState& _s, bool _allowAS
|
||||
m_asm.append((u256)i);
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
default:
|
||||
error<CompilerException>("Unexpected fragment type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,11 +175,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
|
||||
{
|
||||
auto it = _s.vars.find(n);
|
||||
if (it == _s.vars.end())
|
||||
{
|
||||
bool ok;
|
||||
tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32)));
|
||||
_s.stackSize += 32;
|
||||
}
|
||||
error<InvalidName>(std::string("Symbol not found: ") + s);
|
||||
return it->second.first;
|
||||
};
|
||||
|
||||
@ -278,42 +272,43 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
|
||||
bytes data;
|
||||
for (auto const& i: _t)
|
||||
{
|
||||
if (ii == 1)
|
||||
if (ii == 0)
|
||||
{
|
||||
ii++;
|
||||
continue;
|
||||
}
|
||||
else if (ii == 1)
|
||||
{
|
||||
pos = CodeFragment(i, _s);
|
||||
if (pos.m_asm.deposit() != 1)
|
||||
error<InvalidDeposit>();
|
||||
}
|
||||
else if (ii == 2 && !i.tag() && i.which() == sp::utree_type::string_type)
|
||||
else if (i.tag() != 0)
|
||||
{
|
||||
error<InvalidLiteral>();
|
||||
}
|
||||
else if (i.which() == sp::utree_type::string_type)
|
||||
{
|
||||
auto sr = i.get<sp::basic_string<boost::iterator_range<char const*>, sp::utree_type::string_type>>();
|
||||
data = bytes((byte const*)sr.begin(), (byte const*)sr.end());
|
||||
data.insert(data.end(), (byte const *)sr.begin(), (byte const*)sr.end());
|
||||
}
|
||||
else if (ii >= 2 && !i.tag() && i.which() == sp::utree_type::any_type)
|
||||
else if (i.which() == sp::utree_type::any_type)
|
||||
{
|
||||
bigint bi = *i.get<bigint*>();
|
||||
if (bi < 0)
|
||||
error<IntegerOutOfRange>();
|
||||
else if (bi > bigint(u256(0) - 1))
|
||||
{
|
||||
if (ii == 2 && _t.size() == 3)
|
||||
{
|
||||
// One big int - allow it as hex.
|
||||
data.resize(bytesRequired(bi));
|
||||
toBigEndian(bi, data);
|
||||
}
|
||||
else
|
||||
error<IntegerOutOfRange>();
|
||||
}
|
||||
else
|
||||
{
|
||||
data.resize(data.size() + 32);
|
||||
*(h256*)(&data.back() - 31) = (u256)bi;
|
||||
bytes tmp = toCompactBigEndian(bi);
|
||||
data.insert(data.end(), tmp.begin(), tmp.end());
|
||||
}
|
||||
}
|
||||
else if (ii)
|
||||
else
|
||||
{
|
||||
error<InvalidLiteral>();
|
||||
++ii;
|
||||
}
|
||||
|
||||
ii++;
|
||||
}
|
||||
m_asm.append((u256)data.size());
|
||||
m_asm.append(Instruction::DUP1);
|
||||
|
@ -100,11 +100,17 @@ std::string dev::eth::compileLLLToAsm(std::string const& _src, bool _opt, std::v
|
||||
string dev::eth::parseLLL(string const& _src)
|
||||
{
|
||||
sp::utree o;
|
||||
|
||||
try
|
||||
{
|
||||
parseTreeLLL(_src, o);
|
||||
}
|
||||
catch (...) {}
|
||||
catch (...)
|
||||
{
|
||||
killBigints(o);
|
||||
return string();
|
||||
}
|
||||
|
||||
ostringstream ret;
|
||||
debugOutAST(ret, o);
|
||||
killBigints(o);
|
||||
|
@ -100,7 +100,7 @@ void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
|
||||
qi::rule<it, string()> str = '"' > qi::lexeme[+(~qi::char_(std::string("\"") + '\0'))] > '"';
|
||||
qi::rule<it, string()> strsh = '\'' > qi::lexeme[+(~qi::char_(std::string(" ;$@()[]{}:\n\t") + '\0'))];
|
||||
qi::rule<it, symbol_type()> symbol = qi::lexeme[+(~qi::char_(std::string(" $@[]{}:();\"\x01-\x1f\x7f") + '\0'))];
|
||||
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> *qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
|
||||
qi::rule<it, string()> intstr = qi::lexeme[ qi::no_case["0x"][qi::_val = "0x"] >> +qi::char_("0-9a-fA-F")[qi::_val += qi::_1]] | qi::lexeme[+qi::char_("0-9")[qi::_val += qi::_1]];
|
||||
qi::rule<it, sp::utree()> integer = intstr[qi::_val = px::construct<sp::any_ptr>(px::new_<bigint>(qi::_1))];
|
||||
qi::rule<it, space_type, sp::utree()> atom = integer[qi::_val = qi::_1] | (str | strsh)[qi::_val = qi::_1] | symbol[qi::_val = qi::_1];
|
||||
qi::rule<it, space_type, sp::utree::list_type()> seq = '{' > *element > '}';
|
||||
@ -109,7 +109,7 @@ void dev::eth::parseTreeLLL(string const& _s, sp::utree& o_out)
|
||||
qi::rule<it, space_type, sp::utree::list_type()> mstore = '[' > element > ']' > -qi::lit(":") > element;
|
||||
qi::rule<it, space_type, sp::utree::list_type()> sstore = qi::lit("[[") > element > qi::lit("]]") > -qi::lit(":") > element;
|
||||
qi::rule<it, space_type, sp::utree::list_type()> calldataload = qi::lit("$") > element;
|
||||
qi::rule<it, space_type, sp::utree::list_type()> list = '(' > *element > ')';
|
||||
qi::rule<it, space_type, sp::utree::list_type()> list = '(' > +element > ')';
|
||||
|
||||
qi::rule<it, space_type, sp::utree()> extra = sload[tagNode<2>()] | mload[tagNode<1>()] | sstore[tagNode<4>()] | mstore[tagNode<3>()] | seq[tagNode<5>()] | calldataload[tagNode<6>()];
|
||||
element = atom | list | extra;
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <chris@ethereum.org>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <chris@ethereum.org>
|
||||
|
78
libsolidity/analysis/StaticAnalyzer.cpp
Normal file
78
libsolidity/analysis/StaticAnalyzer.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Federico Bond <federicobond@gmail.com>
|
||||
* @date 2016
|
||||
* Static analyzer and checker.
|
||||
*/
|
||||
|
||||
#include <libsolidity/analysis/StaticAnalyzer.h>
|
||||
#include <memory>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace dev;
|
||||
using namespace dev::solidity;
|
||||
|
||||
|
||||
bool StaticAnalyzer::analyze(SourceUnit const& _sourceUnit)
|
||||
{
|
||||
_sourceUnit.accept(*this);
|
||||
return Error::containsOnlyWarnings(m_errors);
|
||||
}
|
||||
|
||||
bool StaticAnalyzer::visit(ContractDefinition const& _contract)
|
||||
{
|
||||
m_library = _contract.isLibrary();
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticAnalyzer::endVisit(ContractDefinition const&)
|
||||
{
|
||||
m_library = false;
|
||||
}
|
||||
|
||||
bool StaticAnalyzer::visit(FunctionDefinition const& _function)
|
||||
{
|
||||
m_nonPayablePublic = _function.isPublic() && !_function.isPayable();
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticAnalyzer::endVisit(FunctionDefinition const&)
|
||||
{
|
||||
m_nonPayablePublic = false;
|
||||
}
|
||||
|
||||
bool StaticAnalyzer::visit(MemberAccess const& _memberAccess)
|
||||
{
|
||||
if (m_nonPayablePublic && !m_library)
|
||||
if (MagicType const* type = dynamic_cast<MagicType const*>(_memberAccess.expression().annotation().type.get()))
|
||||
if (type->kind() == MagicType::Kind::Message && _memberAccess.memberName() == "value")
|
||||
warning(_memberAccess.location(), "\"msg.value\" used in non-payable function. Do you want to add the \"payable\" modifier to this function?");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void StaticAnalyzer::warning(SourceLocation const& _location, string const& _description)
|
||||
{
|
||||
auto err = make_shared<Error>(Error::Type::Warning);
|
||||
*err <<
|
||||
errinfo_sourceLocation(_location) <<
|
||||
errinfo_comment(_description);
|
||||
|
||||
m_errors.push_back(err);
|
||||
}
|
72
libsolidity/analysis/StaticAnalyzer.h
Normal file
72
libsolidity/analysis/StaticAnalyzer.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
This file is part of solidity.
|
||||
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Federico Bond <federicobond@gmail.com>
|
||||
* @date 2016
|
||||
* Static analyzer and checker.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/analysis/TypeChecker.h>
|
||||
#include <libsolidity/ast/Types.h>
|
||||
#include <libsolidity/ast/ASTAnnotations.h>
|
||||
#include <libsolidity/ast/ASTForward.h>
|
||||
#include <libsolidity/ast/ASTVisitor.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* The module that performs static analysis on the AST.
|
||||
*/
|
||||
class StaticAnalyzer: private ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
/// @param _errors the reference to the list of errors and warnings to add them found during static analysis.
|
||||
explicit StaticAnalyzer(ErrorList& _errors): m_errors(_errors) {}
|
||||
|
||||
/// Performs static analysis on the given source unit and all of its sub-nodes.
|
||||
/// @returns true iff all checks passed. Note even if all checks passed, errors() can still contain warnings
|
||||
bool analyze(SourceUnit const& _sourceUnit);
|
||||
|
||||
private:
|
||||
/// Adds a new warning to the list of errors.
|
||||
void warning(SourceLocation const& _location, std::string const& _description);
|
||||
|
||||
virtual bool visit(ContractDefinition const& _contract) override;
|
||||
virtual void endVisit(ContractDefinition const& _contract) override;
|
||||
|
||||
virtual bool visit(FunctionDefinition const& _function) override;
|
||||
virtual void endVisit(FunctionDefinition const& _function) override;
|
||||
|
||||
virtual bool visit(MemberAccess const& _memberAccess) override;
|
||||
|
||||
ErrorList& m_errors;
|
||||
|
||||
/// Flag that indicates whether the current contract definition is a library.
|
||||
bool m_library = false;
|
||||
|
||||
/// Flag that indicates whether a public function does not contain the "payable" modifier.
|
||||
bool m_nonPayablePublic = false;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libsolidity/analysis/SyntaxChecker.h>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -1529,6 +1529,8 @@ bool TypeChecker::visit(Identifier const& _identifier)
|
||||
!!annotation.referencedDeclaration,
|
||||
"Referenced declaration is null after overload resolution."
|
||||
);
|
||||
auto variableDeclaration = dynamic_cast<VariableDeclaration const*>(annotation.referencedDeclaration);
|
||||
annotation.isConstant = variableDeclaration != nullptr && variableDeclaration->isConstant();
|
||||
annotation.isLValue = annotation.referencedDeclaration->isLValue();
|
||||
annotation.type = annotation.referencedDeclaration->type();
|
||||
if (!annotation.type)
|
||||
@ -1612,7 +1614,10 @@ void TypeChecker::requireLValue(Expression const& _expression)
|
||||
{
|
||||
_expression.annotation().lValueRequested = true;
|
||||
_expression.accept(*this);
|
||||
if (!_expression.annotation().isLValue)
|
||||
|
||||
if (_expression.annotation().isConstant)
|
||||
typeError(_expression.location(), "Cannot assign to a constant variable.");
|
||||
else if (!_expression.annotation().isLValue)
|
||||
typeError(_expression.location(), "Expression has to be an lvalue.");
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -63,6 +63,15 @@ SourceUnitAnnotation& SourceUnit::annotation() const
|
||||
return static_cast<SourceUnitAnnotation&>(*m_annotation);
|
||||
}
|
||||
|
||||
string Declaration::sourceUnitName() const
|
||||
{
|
||||
solAssert(!!m_scope, "");
|
||||
ASTNode const* scope = m_scope;
|
||||
while (dynamic_cast<Declaration const*>(scope) && dynamic_cast<Declaration const*>(scope)->m_scope)
|
||||
scope = dynamic_cast<Declaration const*>(scope)->m_scope;
|
||||
return dynamic_cast<SourceUnit const&>(*scope).annotation().path;
|
||||
}
|
||||
|
||||
ImportAnnotation& ImportDirective::annotation() const
|
||||
{
|
||||
if (!m_annotation)
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -158,6 +158,10 @@ public:
|
||||
ASTNode const* scope() const { return m_scope; }
|
||||
void setScope(ASTNode const* _scope) { m_scope = _scope; }
|
||||
|
||||
/// @returns the source name this declaration is present in.
|
||||
/// Can be combined with annotation().canonicalName to form a globally unique name.
|
||||
std::string sourceUnitName() const;
|
||||
|
||||
virtual bool isLValue() const { return false; }
|
||||
virtual bool isPartOfExternalInterface() const { return false; }
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -154,6 +154,8 @@ struct ExpressionAnnotation: ASTAnnotation
|
||||
{
|
||||
/// Inferred type of the expression.
|
||||
TypePointer type;
|
||||
/// Whether the expression is a constant variable
|
||||
bool isConstant = false;
|
||||
/// Whether it is an LValue (i.e. something that can be assigned to).
|
||||
bool isLValue = false;
|
||||
/// Whether the expression is used in a context where the LValue is actually required.
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Lefteris <lefteris@ethdev.com>
|
||||
@ -24,6 +24,7 @@
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
#include <libdevcore/UTF8.h>
|
||||
#include <libsolidity/ast/AST.h>
|
||||
#include <libsolidity/interface/Exceptions.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -173,9 +174,9 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
|
||||
{
|
||||
addJsonNode(_node, "FunctionDefinition", {
|
||||
make_pair("name", _node.name()),
|
||||
make_pair("public", _node.isPublic()),
|
||||
make_pair("constant", _node.isDeclaredConst()),
|
||||
make_pair("payable", _node.isPayable())
|
||||
make_pair("payable", _node.isPayable()),
|
||||
make_pair("visibility", visibility(_node.visibility()))
|
||||
}, true);
|
||||
return true;
|
||||
}
|
||||
@ -228,13 +229,9 @@ bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
|
||||
|
||||
bool ASTJsonConverter::visit(FunctionTypeName const& _node)
|
||||
{
|
||||
string visibility = "internal";
|
||||
if (_node.visibility() == Declaration::Visibility::External)
|
||||
visibility = "external";
|
||||
|
||||
addJsonNode(_node, "FunctionTypeName", {
|
||||
make_pair("payable", _node.isPayable()),
|
||||
make_pair("visibility", visibility),
|
||||
make_pair("visibility", visibility(_node.visibility())),
|
||||
make_pair("constant", _node.isDeclaredConst())
|
||||
}, true);
|
||||
return true;
|
||||
@ -318,7 +315,7 @@ bool ASTJsonConverter::visit(Throw const& _node)
|
||||
|
||||
bool ASTJsonConverter::visit(VariableDeclarationStatement const& _node)
|
||||
{
|
||||
addJsonNode(_node, "VariableDefinitionStatement", {}, true);
|
||||
addJsonNode(_node, "VariableDeclarationStatement", {}, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -407,7 +404,7 @@ bool ASTJsonConverter::visit(Identifier const& _node)
|
||||
|
||||
bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
|
||||
{
|
||||
addJsonNode(_node, "ElementaryTypenameExpression", {
|
||||
addJsonNode(_node, "ElementaryTypeNameExpression", {
|
||||
make_pair("value", _node.typeName().toString()),
|
||||
make_pair("type", type(_node))
|
||||
});
|
||||
@ -417,9 +414,8 @@ bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node)
|
||||
bool ASTJsonConverter::visit(Literal const& _node)
|
||||
{
|
||||
char const* tokenString = Token::toString(_node.token());
|
||||
size_t invalidPos = 0;
|
||||
Json::Value value{_node.value()};
|
||||
if (!dev::validate(_node.value(), invalidPos))
|
||||
if (!dev::validateUTF8(_node.value()))
|
||||
value = Json::nullValue;
|
||||
Token::Value subdenomination = Token::Value(_node.subDenomination());
|
||||
addJsonNode(_node, "Literal", {
|
||||
@ -657,6 +653,23 @@ void ASTJsonConverter::process()
|
||||
processed = true;
|
||||
}
|
||||
|
||||
string ASTJsonConverter::visibility(Declaration::Visibility const& _visibility)
|
||||
{
|
||||
switch (_visibility)
|
||||
{
|
||||
case Declaration::Visibility::Private:
|
||||
return "private";
|
||||
case Declaration::Visibility::Internal:
|
||||
return "internal";
|
||||
case Declaration::Visibility::Public:
|
||||
return "public";
|
||||
case Declaration::Visibility::External:
|
||||
return "external";
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown declaration visibility."));
|
||||
}
|
||||
}
|
||||
|
||||
string ASTJsonConverter::type(Expression const& _expression)
|
||||
{
|
||||
return _expression.annotation().type ? _expression.annotation().type->toString() : "Unknown";
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Lefteris <lefteris@ethdev.com>
|
||||
@ -152,6 +152,7 @@ private:
|
||||
bool _hasChildren
|
||||
);
|
||||
std::string sourceLocationToString(SourceLocation const& _location) const;
|
||||
std::string visibility(Declaration::Visibility const& _visibility);
|
||||
std::string type(Expression const& _expression);
|
||||
std::string type(VariableDeclaration const& _varDecl);
|
||||
inline void goUp()
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -251,6 +251,19 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
|
||||
return members;
|
||||
}
|
||||
|
||||
bool isValidShiftAndAmountType(Token::Value _operator, Type const& _shiftAmountType)
|
||||
{
|
||||
// Disable >>> here.
|
||||
if (_operator == Token::SHR)
|
||||
return false;
|
||||
else if (IntegerType const* otherInt = dynamic_cast<decltype(otherInt)>(&_shiftAmountType))
|
||||
return !otherInt->isAddress();
|
||||
else if (RationalNumberType const* otherRat = dynamic_cast<decltype(otherRat)>(&_shiftAmountType))
|
||||
return otherRat->integerType() && !otherRat->integerType()->isSigned();
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
|
||||
m_bits(_bits), m_modifier(_modifier)
|
||||
{
|
||||
@ -340,6 +353,17 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
|
||||
_other->category() != category()
|
||||
)
|
||||
return TypePointer();
|
||||
if (Token::isShiftOp(_operator))
|
||||
{
|
||||
// Shifts are not symmetric with respect to the type
|
||||
if (isAddress())
|
||||
return TypePointer();
|
||||
if (isValidShiftAndAmountType(_operator, *_other))
|
||||
return shared_from_this();
|
||||
else
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
auto commonType = Type::commonType(shared_from_this(), _other); //might be a integer or fixed point
|
||||
if (!commonType)
|
||||
return TypePointer();
|
||||
@ -879,7 +903,8 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
||||
else if (auto arrayType = dynamic_cast<ArrayType const*>(&_convertTo))
|
||||
return
|
||||
arrayType->isByteArray() &&
|
||||
!(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer());
|
||||
!(arrayType->dataStoredIn(DataLocation::Storage) && arrayType->isPointer()) &&
|
||||
!(arrayType->isString() && !isValidUTF8());
|
||||
else
|
||||
return false;
|
||||
}
|
||||
@ -895,7 +920,7 @@ std::string StringLiteralType::toString(bool) const
|
||||
{
|
||||
size_t invalidSequence;
|
||||
|
||||
if (!dev::validate(m_value, invalidSequence))
|
||||
if (!dev::validateUTF8(m_value, invalidSequence))
|
||||
return "literal_string (contains invalid UTF-8 sequence at position " + dev::toString(invalidSequence) + ")";
|
||||
|
||||
return "literal_string \"" + m_value + "\"";
|
||||
@ -906,6 +931,11 @@ TypePointer StringLiteralType::mobileType() const
|
||||
return make_shared<ArrayType>(DataLocation::Memory, true);
|
||||
}
|
||||
|
||||
bool StringLiteralType::isValidUTF8() const
|
||||
{
|
||||
return dev::validateUTF8(m_value);
|
||||
}
|
||||
|
||||
shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal)
|
||||
{
|
||||
if (_literal.length() <= 32)
|
||||
@ -948,6 +978,14 @@ TypePointer FixedBytesType::unaryOperatorResult(Token::Value _operator) const
|
||||
|
||||
TypePointer FixedBytesType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
|
||||
{
|
||||
if (Token::isShiftOp(_operator))
|
||||
{
|
||||
if (isValidShiftAndAmountType(_operator, *_other))
|
||||
return shared_from_this();
|
||||
else
|
||||
return TypePointer();
|
||||
}
|
||||
|
||||
auto commonType = dynamic_pointer_cast<FixedBytesType const>(Type::commonType(shared_from_this(), _other));
|
||||
if (!commonType)
|
||||
return TypePointer();
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -425,6 +425,8 @@ public:
|
||||
virtual std::string toString(bool) const override;
|
||||
virtual TypePointer mobileType() const override;
|
||||
|
||||
bool isValidUTF8() const;
|
||||
|
||||
std::string const& value() const { return m_value; }
|
||||
|
||||
private:
|
||||
@ -1115,6 +1117,8 @@ public:
|
||||
|
||||
virtual std::string toString(bool _short) const override;
|
||||
|
||||
Kind kind() const { return m_kind; }
|
||||
|
||||
private:
|
||||
Kind m_kind;
|
||||
};
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -200,7 +200,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
|
||||
else if (sourceBaseType->isValueType())
|
||||
CompilerUtils(m_context).loadFromMemoryDynamic(*sourceBaseType, fromCalldata, true, false);
|
||||
else
|
||||
solAssert(false, "Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
|
||||
solUnimplemented("Copying of type " + _sourceType.toString(false) + " to storage not yet supported.");
|
||||
// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset] <source_value>...
|
||||
solAssert(
|
||||
2 + byteOffsetSize + sourceBaseType->sizeOnStack() <= 16,
|
||||
@ -335,9 +335,14 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
|
||||
if (baseSize > 1)
|
||||
m_context << u256(baseSize) << Instruction::MUL;
|
||||
// stack: <target> <source> <size>
|
||||
//@TODO do not use ::CALL if less than 32 bytes?
|
||||
m_context << Instruction::DUP1 << Instruction::DUP4 << Instruction::DUP4;
|
||||
utils.memoryCopy();
|
||||
// We can resort to copying full 32 bytes only if
|
||||
// - the length is known to be a multiple of 32 or
|
||||
// - we will pad to full 32 bytes later anyway.
|
||||
if (((baseSize % 32) == 0) || _padToWordBoundaries)
|
||||
utils.memoryCopy32();
|
||||
else
|
||||
utils.memoryCopy();
|
||||
|
||||
m_context << Instruction::SWAP1 << Instruction::POP;
|
||||
// stack: <target> <size>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -30,11 +30,13 @@ using namespace dev::solidity;
|
||||
|
||||
void Compiler::compileContract(
|
||||
ContractDefinition const& _contract,
|
||||
std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts
|
||||
std::map<const ContractDefinition*, eth::Assembly const*> const& _contracts,
|
||||
bytes const& _metadata
|
||||
)
|
||||
{
|
||||
ContractCompiler runtimeCompiler(nullptr, m_runtimeContext, m_optimize);
|
||||
runtimeCompiler.compileContract(_contract, _contracts);
|
||||
m_runtimeContext.appendAuxiliaryData(_metadata);
|
||||
|
||||
// This might modify m_runtimeContext because it can access runtime functions at
|
||||
// creation time.
|
||||
@ -42,12 +44,6 @@ void Compiler::compileContract(
|
||||
m_runtimeSub = creationCompiler.compileConstructor(_contract, _contracts);
|
||||
|
||||
m_context.optimise(m_optimize, m_optimizeRuns);
|
||||
|
||||
if (_contract.isLibrary())
|
||||
{
|
||||
solAssert(m_runtimeSub != size_t(-1), "");
|
||||
m_context.injectVersionStampIntoSub(m_runtimeSub);
|
||||
}
|
||||
}
|
||||
|
||||
void Compiler::compileClone(
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -42,7 +42,8 @@ public:
|
||||
|
||||
void compileContract(
|
||||
ContractDefinition const& _contract,
|
||||
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts
|
||||
std::map<ContractDefinition const*, eth::Assembly const*> const& _contracts,
|
||||
bytes const& _metadata
|
||||
);
|
||||
/// Compiles a contract that uses DELEGATECALL to call into a pre-deployed version of the given
|
||||
/// contract at runtime, but contains the full creation-time code.
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -202,6 +202,8 @@ void CompilerContext::appendInlineAssembly(
|
||||
return false;
|
||||
unsigned stackDepth = _localVariables.end() - it;
|
||||
int stackDiff = _assembly.deposit() - startStackHeight + stackDepth;
|
||||
if (_context == assembly::CodeGenerator::IdentifierContext::LValue)
|
||||
stackDiff -= 1;
|
||||
if (stackDiff < 1 || stackDiff > 16)
|
||||
BOOST_THROW_EXCEPTION(
|
||||
CompilerError() <<
|
||||
@ -217,14 +219,7 @@ void CompilerContext::appendInlineAssembly(
|
||||
return true;
|
||||
};
|
||||
|
||||
solAssert(assembly::InlineAssemblyStack().parseAndAssemble(*assembly, *m_asm, identifierAccess), "");
|
||||
}
|
||||
|
||||
void CompilerContext::injectVersionStampIntoSub(size_t _subIndex)
|
||||
{
|
||||
eth::Assembly& sub = m_asm->sub(_subIndex);
|
||||
sub.injectStart(Instruction::POP);
|
||||
sub.injectStart(fromBigEndian<u256>(binaryVersion()));
|
||||
solAssert(assembly::InlineAssemblyStack().parseAndAssemble(*assembly, *m_asm, identifierAccess), "Failed to assemble inline assembly block.");
|
||||
}
|
||||
|
||||
FunctionDefinition const& CompilerContext::resolveVirtualFunction(
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -152,8 +152,8 @@ public:
|
||||
std::map<std::string, std::string> const& _replacements = std::map<std::string, std::string>{}
|
||||
);
|
||||
|
||||
/// Prepends "PUSH <compiler version number> POP"
|
||||
void injectVersionStampIntoSub(size_t _subIndex);
|
||||
/// Appends arbitrary data to the end of the bytecode.
|
||||
void appendAuxiliaryData(bytes const& _data) { m_asm->appendAuxiliaryDataToEnd(_data); }
|
||||
|
||||
void optimise(bool _fullOptimsation, unsigned _runs = 200) { m_asm->optimise(_fullOptimsation, true, _runs); }
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -298,21 +298,73 @@ void CompilerUtils::zeroInitialiseMemoryArray(ArrayType const& _type)
|
||||
m_context << Instruction::SWAP1 << Instruction::POP;
|
||||
}
|
||||
|
||||
void CompilerUtils::memoryCopyPrecompile()
|
||||
{
|
||||
// Stack here: size target source
|
||||
|
||||
m_context.appendInlineAssembly(R"(
|
||||
{
|
||||
let words := div(add(len, 31), 32)
|
||||
let cost := add(15, mul(3, words))
|
||||
jumpi(invalidJumpLabel, iszero(call(cost, $identityContractAddress, 0, src, len, dst, len)))
|
||||
}
|
||||
)",
|
||||
{ "len", "dst", "src" },
|
||||
map<string, string> {
|
||||
{ "$identityContractAddress", toString(identityContractAddress) }
|
||||
}
|
||||
);
|
||||
m_context << Instruction::POP << Instruction::POP << Instruction::POP;
|
||||
}
|
||||
|
||||
void CompilerUtils::memoryCopy32()
|
||||
{
|
||||
// Stack here: size target source
|
||||
|
||||
m_context.appendInlineAssembly(R"(
|
||||
{
|
||||
jumpi(end, eq(len, 0))
|
||||
start:
|
||||
mstore(dst, mload(src))
|
||||
jumpi(end, iszero(gt(len, 32)))
|
||||
dst := add(dst, 32)
|
||||
src := add(src, 32)
|
||||
len := sub(len, 32)
|
||||
jump(start)
|
||||
end:
|
||||
}
|
||||
)",
|
||||
{ "len", "dst", "src" }
|
||||
);
|
||||
m_context << Instruction::POP << Instruction::POP << Instruction::POP;
|
||||
}
|
||||
|
||||
void CompilerUtils::memoryCopy()
|
||||
{
|
||||
// Stack here: size target source
|
||||
// stack for call: outsize target size source value contract gas
|
||||
//@TODO do not use ::CALL if less than 32 bytes?
|
||||
m_context << Instruction::DUP3 << Instruction::SWAP1;
|
||||
m_context << u256(0) << u256(identityContractAddress);
|
||||
// compute gas costs
|
||||
m_context << u256(32) << Instruction::DUP5 << u256(31) << Instruction::ADD;
|
||||
static unsigned c_identityGas = 15;
|
||||
static unsigned c_identityWordGas = 3;
|
||||
m_context << Instruction::DIV << u256(c_identityWordGas) << Instruction::MUL;
|
||||
m_context << u256(c_identityGas) << Instruction::ADD;
|
||||
m_context << Instruction::CALL;
|
||||
m_context << Instruction::POP; // ignore return value
|
||||
|
||||
m_context.appendInlineAssembly(R"(
|
||||
{
|
||||
// copy 32 bytes at once
|
||||
start32:
|
||||
jumpi(end32, lt(len, 32))
|
||||
mstore(dst, mload(src))
|
||||
dst := add(dst, 32)
|
||||
src := add(src, 32)
|
||||
len := sub(len, 32)
|
||||
jump(start32)
|
||||
end32:
|
||||
|
||||
// copy the remainder (0 < len < 32)
|
||||
let mask := sub(exp(256, sub(32, len)), 1)
|
||||
let srcpart := and(mload(src), not(mask))
|
||||
let dstpart := and(mload(dst), mask)
|
||||
mstore(dst, or(srcpart, dstpart))
|
||||
}
|
||||
)",
|
||||
{ "len", "dst", "src" }
|
||||
);
|
||||
m_context << Instruction::POP << Instruction::POP << Instruction::POP;
|
||||
}
|
||||
|
||||
void CompilerUtils::splitExternalFunctionType(bool _leftAligned)
|
||||
@ -358,7 +410,7 @@ void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function)
|
||||
Instruction::OR;
|
||||
}
|
||||
|
||||
void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded)
|
||||
void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded, bool _chopSignBits)
|
||||
{
|
||||
// For a type extension, we need to remove all higher-order bits that we might have ignored in
|
||||
// previous operations.
|
||||
@ -370,6 +422,12 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
|
||||
Type::Category targetTypeCategory = _targetType.category();
|
||||
|
||||
bool enumOverflowCheckPending = (targetTypeCategory == Type::Category::Enum || stackTypeCategory == Type::Category::Enum);
|
||||
bool chopSignBitsPending = _chopSignBits && targetTypeCategory == Type::Category::Integer;
|
||||
if (chopSignBitsPending)
|
||||
{
|
||||
const IntegerType& targetIntegerType = dynamic_cast<const IntegerType &>(_targetType);
|
||||
chopSignBitsPending = targetIntegerType.isSigned();
|
||||
}
|
||||
|
||||
switch (stackTypeCategory)
|
||||
{
|
||||
@ -482,6 +540,14 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
|
||||
cleanHigherOrderBits(typeOnStack);
|
||||
else if (_cleanupNeeded)
|
||||
cleanHigherOrderBits(targetType);
|
||||
if (chopSignBitsPending)
|
||||
{
|
||||
if (typeOnStack.numBits() < 256)
|
||||
m_context
|
||||
<< ((u256(1) << typeOnStack.numBits()) - 1)
|
||||
<< Instruction::AND;
|
||||
chopSignBitsPending = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -724,10 +790,15 @@ void CompilerUtils::convertType(Type const& _typeOnStack, Type const& _targetTyp
|
||||
default:
|
||||
// All other types should not be convertible to non-equal types.
|
||||
solAssert(_typeOnStack == _targetType, "Invalid type conversion requested.");
|
||||
if (_cleanupNeeded && _targetType.canBeStored() && _targetType.storageBytes() < 32)
|
||||
m_context
|
||||
<< ((u256(1) << (8 * _targetType.storageBytes())) - 1)
|
||||
<< Instruction::AND;
|
||||
break;
|
||||
}
|
||||
|
||||
solAssert(!enumOverflowCheckPending, "enum overflow checking missing.");
|
||||
solAssert(!chopSignBitsPending, "forgot to chop the sign bits.");
|
||||
}
|
||||
|
||||
void CompilerUtils::pushZeroValue(Type const& _type)
|
||||
@ -881,9 +952,9 @@ void CompilerUtils::storeStringData(bytesConstRef _data)
|
||||
}
|
||||
}
|
||||
|
||||
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries)
|
||||
unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWords)
|
||||
{
|
||||
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
|
||||
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
|
||||
bool isExternalFunctionType = false;
|
||||
if (auto const* funType = dynamic_cast<FunctionType const*>(&_type))
|
||||
if (funType->location() == FunctionType::Location::External)
|
||||
@ -906,6 +977,8 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda
|
||||
if (leftAligned)
|
||||
m_context << shiftFactor << Instruction::MUL;
|
||||
}
|
||||
if (_fromCalldata)
|
||||
convertType(_type, _type, true);
|
||||
|
||||
return numBytes;
|
||||
}
|
||||
@ -920,16 +993,17 @@ void CompilerUtils::cleanHigherOrderBits(IntegerType const& _typeOnStack)
|
||||
m_context << ((u256(1) << _typeOnStack.numBits()) - 1) << Instruction::AND;
|
||||
}
|
||||
|
||||
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const
|
||||
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords)
|
||||
{
|
||||
unsigned numBytes = _type.calldataEncodedSize(_padToWordBoundaries);
|
||||
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
|
||||
bool leftAligned = _type.category() == Type::Category::FixedBytes;
|
||||
if (numBytes == 0)
|
||||
m_context << Instruction::POP;
|
||||
else
|
||||
{
|
||||
solAssert(numBytes <= 32, "Memory store of more than 32 bytes requested.");
|
||||
if (numBytes != 32 && !leftAligned && !_padToWordBoundaries)
|
||||
convertType(_type, _type, true);
|
||||
if (numBytes != 32 && !leftAligned && !_padToWords)
|
||||
// shift the value accordingly before storing
|
||||
m_context << (u256(1) << ((32 - numBytes) * 8)) << Instruction::MUL;
|
||||
}
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -52,13 +52,13 @@ public:
|
||||
/// @param _offset offset in memory (or calldata)
|
||||
/// @param _type data type to load
|
||||
/// @param _fromCalldata if true, load from calldata, not from memory
|
||||
/// @param _padToWordBoundaries if true, assume the data is padded to word (32 byte) boundaries
|
||||
/// @param _padToWords if true, assume the data is padded to full words (32 bytes)
|
||||
/// @returns the number of bytes consumed in memory.
|
||||
unsigned loadFromMemory(
|
||||
unsigned _offset,
|
||||
Type const& _type = IntegerType(256),
|
||||
bool _fromCalldata = false,
|
||||
bool _padToWordBoundaries = false
|
||||
bool _padToWords = false
|
||||
);
|
||||
/// Dynamic version of @see loadFromMemory, expects the memory offset on the stack.
|
||||
/// Stack pre: memory_offset
|
||||
@ -66,7 +66,7 @@ public:
|
||||
void loadFromMemoryDynamic(
|
||||
Type const& _type,
|
||||
bool _fromCalldata = false,
|
||||
bool _padToWordBoundaries = true,
|
||||
bool _padToWords = true,
|
||||
bool _keepUpdatedMemoryOffset = true
|
||||
);
|
||||
/// Stores a 256 bit integer from stack in memory.
|
||||
@ -76,11 +76,11 @@ public:
|
||||
/// Dynamic version of @see storeInMemory, expects the memory offset below the value on the stack
|
||||
/// and also updates that. For reference types, only copies the data pointer. Fails for
|
||||
/// non-memory-references.
|
||||
/// @param _padToWordBoundaries if true, adds zeros to pad to multiple of 32 bytes. Array elements
|
||||
/// @param _padToWords if true, adds zeros to pad to multiple of 32 bytes. Array elements
|
||||
/// are always padded (except for byte arrays), regardless of this parameter.
|
||||
/// Stack pre: memory_offset value...
|
||||
/// Stack post: (memory_offset+length)
|
||||
void storeInMemoryDynamic(Type const& _type, bool _padToWordBoundaries = true);
|
||||
void storeInMemoryDynamic(Type const& _type, bool _padToWords = true);
|
||||
|
||||
/// Copies values (of types @a _givenTypes) given on the stack to a location in memory given
|
||||
/// at the stack top, encoding them according to the ABI as the given types @a _targetTypes.
|
||||
@ -88,7 +88,7 @@ public:
|
||||
/// Stack pre: <v1> <v2> ... <vn> <memptr>
|
||||
/// Stack post: <memptr_updated>
|
||||
/// Does not touch the memory-free pointer.
|
||||
/// @param _padToWordBoundaries if false, all values are concatenated without padding.
|
||||
/// @param _padToWords if false, all values are concatenated without padding.
|
||||
/// @param _copyDynamicDataInPlace if true, dynamic types is stored (without length)
|
||||
/// together with fixed-length data.
|
||||
/// @param _encodeAsLibraryTypes if true, encodes for a library function, e.g. does not
|
||||
@ -98,7 +98,7 @@ public:
|
||||
void encodeToMemory(
|
||||
TypePointers const& _givenTypes = {},
|
||||
TypePointers const& _targetTypes = {},
|
||||
bool _padToWordBoundaries = true,
|
||||
bool _padToWords = true,
|
||||
bool _copyDynamicDataInPlace = false,
|
||||
bool _encodeAsLibraryTypes = false
|
||||
);
|
||||
@ -112,6 +112,14 @@ public:
|
||||
/// Uses a CALL to the identity contract to perform a memory-to-memory copy.
|
||||
/// Stack pre: <size> <target> <source>
|
||||
/// Stack post:
|
||||
void memoryCopyPrecompile();
|
||||
/// Copies full 32 byte words in memory (regions cannot overlap), i.e. may copy more than length.
|
||||
/// Stack pre: <size> <target> <source>
|
||||
/// Stack post:
|
||||
void memoryCopy32();
|
||||
/// Copies data in memory (regions cannot overlap).
|
||||
/// Stack pre: <size> <target> <source>
|
||||
/// Stack post:
|
||||
void memoryCopy();
|
||||
|
||||
/// Converts the combined and left-aligned (right-aligned if @a _rightAligned is true)
|
||||
@ -130,7 +138,8 @@ public:
|
||||
/// if a reference type is converted from calldata or storage to memory.
|
||||
/// If @a _cleanupNeeded, high order bits cleanup is also done if no type conversion would be
|
||||
/// necessary.
|
||||
void convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false);
|
||||
/// If @a _chopSignBits, the function resets the signed bits out of the width of the signed integer.
|
||||
void convertType(Type const& _typeOnStack, Type const& _targetType, bool _cleanupNeeded = false, bool _chopSignBits = false);
|
||||
|
||||
/// Creates a zero-value for the given type and puts it onto the stack. This might allocate
|
||||
/// memory for memory references.
|
||||
@ -184,9 +193,9 @@ private:
|
||||
void cleanHigherOrderBits(IntegerType const& _typeOnStack);
|
||||
|
||||
/// Prepares the given type for storing in memory by shifting it if necessary.
|
||||
unsigned prepareMemoryStore(Type const& _type, bool _padToWordBoundaries) const;
|
||||
unsigned prepareMemoryStore(Type const& _type, bool _padToWords);
|
||||
/// Loads type from memory assuming memory offset is on stack top.
|
||||
unsigned loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWordBoundaries);
|
||||
unsigned loadFromMemoryHelper(Type const& _type, bool _fromCalldata, bool _padToWords);
|
||||
|
||||
CompilerContext& m_context;
|
||||
};
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
@ -583,7 +583,7 @@ bool ContractCompiler::visit(InlineAssembly const& _inlineAssembly)
|
||||
// lvalue context
|
||||
auto variable = dynamic_cast<VariableDeclaration const*>(decl);
|
||||
solAssert(
|
||||
!!variable || !m_context.isLocalVariable(variable),
|
||||
!!variable && m_context.isLocalVariable(variable),
|
||||
"Can only assign to stack variables in inline assembly."
|
||||
);
|
||||
unsigned size = variable->type()->sizeOnStack();
|
||||
@ -862,8 +862,6 @@ void ContractCompiler::appendModifierOrFunctionCode()
|
||||
CompilerUtils::sizeOnStack(modifier.parameters()) +
|
||||
CompilerUtils::sizeOnStack(modifier.localVariables());
|
||||
codeBlock = &modifier.body();
|
||||
|
||||
codeBlock = &modifier.body();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
/*
|
||||
This file is part of cpp-ethereum.
|
||||
This file is part of solidity.
|
||||
|
||||
cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
solidity is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
cpp-ethereum is distributed in the hope that it will be useful,
|
||||
solidity is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
|
||||
along with solidity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
/**
|
||||
* @author Christian <c@ethdev.com>
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user