Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ Language Features:

Compiler Features:
* Commandline Interface: Remove support for the experimental Language Server Protocol (LSP) mode.
* Commandline Interface: Add the experimental `--ir-ethdebug` output and the assembler-mode `--ethdebug-input` option, which carry the semantic debug info of the Yul IR across a textual Yul boundary.
* EVM: Deprecate support for "constantinople", "petersburg", "istanbul" and "berlin" EVM versions.
* Evmasm Optimizer: Improve performance of block deduplicator.
* General: Improve performance throughout the compiler using Boost's flat versions of unordered set and map.
* General: Remove support for the experimental Generic Solidity prototype (`pragma experimental solidity`).
* General: Replace the current greedy stack shuffler in the experimental SSA CFG pipeline with a planning one.
* SMTChecker: Emit a deprecation warning for the BMC engine.
* SMTChecker: Support `block.slotnum`.
* Standard JSON Interface: Add the experimental `irEthdebug` output and `auxiliaryInput.ethdebug` input, which carry the semantic debug info of the Yul IR across a textual Yul boundary.
* Yul: Add the `@ast-id-instance` debug info annotation, which distinguishes Yul scopes cloned from the same Solidity definition.
* Yul Optimizer: `LoopInvariantCodeMotion` can now move expressions depending on function parameters out of loops.
* Yul Optimizer: `UnusedStoreEliminator` can now recognize redundant memory and storage operations whose start offset or length is a function parameter.
Expand Down
14 changes: 6 additions & 8 deletions docs/compiler-guide/ethdebug_internal_debug_info.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,11 @@ Accordingly, ``ethdebug`` depends on the ``ast-id`` ``--debug-info`` component.
CLI and Standard JSON input reject a debug-info selection containing ``ethdebug`` without ``ast-id``.
Selecting an ethdebug output does not modify the debug-info selection, just as ``--ir-optimized`` does not imply ``--optimize``.
Without ``ethdebug`` in the selection the program outputs are still produced from the assembly, but carry none of the semantic debug info the component adds; the resources and compilation outputs do not depend on it.
The sidecar carries the semantic debug info itself, so requesting the ``irEthdebug`` output or attaching ``auxiliaryInput.ethdebug`` without ``ethdebug`` in the selection is an error.

Core Structures
===============

.. note::

Of the types named below, only ``langutil::DebugData`` exists in the compiler today.
The ``SemanticDebugScope`` family and the ``semanticDebugScope`` field on ``DebugData`` are planned additions and will arrive with the implementation pull requests.

``langutil::DebugData`` is the debug payload carried by Yul AST nodes.
The sidecar envelope and variable records are compiler-specific.
Type documents and pointer documents follow the public `type <https://github.com/ethdebug/format/blob/main/schemas/type.schema.yaml>`_ and `pointer <https://github.com/ethdebug/format/blob/main/schemas/pointer.schema.yaml>`_ schemas, with one internal pointer expression for unresolved Yul locals.
Expand Down Expand Up @@ -398,15 +394,17 @@ Each source record in ``ethdebug.compilation`` maps its ID to the source path an
Instance ``0`` is written explicitly.

Readers reject an unknown format, an unsupported version, malformed sidecar fields, and keys that do not parse as decimal integers in the documented ranges.
Writers emit deterministic output by ordering both key levels in ascending numeric order.
Writers emit deterministic output: the compiler's JSON writer orders object members lexicographically by key, so the decimal keys of both levels appear in that order rather than in numeric order.
Readers do not depend on key order.

Compiler Interfaces
-------------------

Standard JSON uses these fields:

- Solidity output ``contracts[<source>][<contract>].ir`` contains the Yul text.
- Solidity output ``contracts[<source>][<contract>].irEthdebug`` contains its semantic sidecar.
- Solidity output ``contracts[<source>][<contract>].irEthdebug`` contains the semantic sidecar of its ``ir`` output.
The optimized IR is not a supported sidecar input yet: the Yul pipeline renames generated locals, and optimizer passes do not maintain the records (see the staging note above).
- Yul input ``auxiliaryInput.ethdebug`` supplies the sidecar for the Yul source.
- Yul output ``irEthdebug`` emits the updated sidecar again.

Expand All @@ -420,7 +418,7 @@ The sidecar is both compiler input and compiler output, allowing the same debug

.. note::

For implementation testing, ``EthdebugTest`` will add ``Contract.semantic`` as a direct view of the serialized sidecar.
For implementation testing, ``EthdebugTest`` exposes ``Contract.semantic`` as a direct view of the serialized sidecar.

Required Variable Coverage
==========================
Expand Down
22 changes: 20 additions & 2 deletions docs/using-the-compiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,20 @@ Input Description
}
}
},
// Optional auxiliary inputs.
"auxiliaryInput": {
// Semantic debug info for the Yul input (experimental): the object the Solidity
// `irEthdebug` output emits for the `ir` output, attached to the Yul by its `@ast-id`
// annotations. Requires `ethdebug` in `settings.debug.debugInfo`. Yul optimization is
// not yet supported together with it.
"ethdebug": {
"format": "solidity-ethdebug-semantic-data",
"version": 1,
"contractName": "ContractName",
"resources": {/* ... */},
"scopes": {/* ... */}
}
},
// Optional
"settings":
{
Expand Down Expand Up @@ -398,7 +412,7 @@ Input Description
// `ethdebug` without `ast-id` is an error. Requesting an ethdebug output does not
// change this selection; without `ethdebug` in it the `evm.bytecode.ethdebug` and
// `evm.deployedBytecode.ethdebug` outputs carry none of the semantic debug info
// this component adds.
// this component adds, and `irEthdebug` and `auxiliaryInput.ethdebug` are an error.
// - `*`: Wildcard value that can be used to request all non-experimental components.
"debugInfo": ["location", "snippet", "ast-id", "ethdebug"]
},
Expand Down Expand Up @@ -451,6 +465,7 @@ Input Description
// userdoc - User documentation (natspec)
// metadata - Metadata
// ir - Yul intermediate representation of the code before optimization
// irEthdebug - Semantic debug info of the `ir` output: type documents, pointer templates and the variable scopes keyed by AST ID. Requires `ethdebug` in `settings.debug.debugInfo`. (experimental)
// irAst - AST of Yul intermediate representation of the code before optimization (experimental)
// irOptimized - Intermediate representation after optimization
// irOptimizedAst - AST of intermediate representation after optimization (experimental)
Expand Down Expand Up @@ -608,6 +623,8 @@ Output Description
"devdoc": {},
// Intermediate representation before optimization (string)
"ir": "",
// Semantic debug info of the Yul IR (experimental)
"irEthdebug": {/* ... */},
// AST of intermediate representation before optimization
"irAst": {/* ... */},
// Intermediate representation after optimization (string)
Expand Down Expand Up @@ -773,7 +790,8 @@ The table below details all currently available experimental features.
+-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Non-mainnet EVMs | ``evm`` | yes | ``--evm-version <version name>`` |
+-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| Ethdebug | ``ethdebug`` | no | ``--ethdebug-resources``, ``--ethdebug-compilation``, ``--ethdebug-program``, ``--ethdebug-program-runtime``, ``--debug-info ethdebug`` |
| Ethdebug | ``ethdebug`` | no | ``--ethdebug-resources``, ``--ethdebug-compilation``, ``--ethdebug-program``, ``--ethdebug-program-runtime``, ``--ir-ethdebug``, |
| | | | ``--ethdebug-input``, ``--debug-info ethdebug`` |
+-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
| SSA CFG | ``ssa-cfg`` | yes | ``--via-ssa-cfg`` |
+-----------------------+--------------------------+------------------+-----------------------------------------------------------------------------------------------------------------------------------------+
8 changes: 3 additions & 5 deletions libsolidity/interface/CompilerStack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,8 +1166,6 @@ Json CompilerStack::interfaceSymbols(std::string const& _contractName) const
Json CompilerStack::ethdebug() const
{
solAssert(m_stackState >= AnalysisSuccessful, "Analysis was not successful.");
// The resource tables are derived from analysis results alone, so
// ethdebug.resources is available right after analysis.
ethdebug::Resources resources;
std::map<std::string, unsigned> const sourceIndexMap = sourceIndices();
for (auto const& [name, compiledContract]: m_contracts)
Expand Down Expand Up @@ -1610,9 +1608,9 @@ void CompilerStack::generateIR(ContractDefinition const& _contract, bool _unopti
*compiledContract.yulIR,
compiledContract.yulSemanticDebugData ? &*compiledContract.yulSemanticDebugData : nullptr
);
// The side table pairs with the unoptimized IR: attaching checks every
// pointer against it, and the table is kept as attached. The optimized IR,
// whose variable names differ, is not a supported pairing yet.
// The sidecar pairs with the unoptimized IR: attaching checks every pointer
// against it, and the table is kept as attached. The optimized IR, whose
// variable names differ, is not a supported sidecar input yet.
if (compiledContract.yulSemanticDebugData)
compiledContract.yulSemanticDebugData = stack.semanticDebugData();
if (!_unoptimizedOnly)
Expand Down
20 changes: 20 additions & 0 deletions libsolidity/interface/Ethdebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@

#include <liblangutil/SemanticDebugData.h>

#include <libsolutil/CommonData.h>
#include <libsolutil/Numeric.h>

#include <range/v3/view/map.hpp>

#include <algorithm>
#include <functional>
#include <memory>
Expand Down Expand Up @@ -1019,6 +1022,23 @@ ethdebug::Resources ethdebug::resources(ContractDefinition const& _contract, std
return result;
}

ethdebug::Resources ethdebug::resources(langutil::SemanticDebugDataTable const& _table)
{
Resources result;
result.types = _table.types();
result.pointers = _table.pointerTemplates();
return result;
}

std::optional<schema::program::Context> ethdebug::programContext(langutil::SemanticDebugDataTable const& _table)
{
langutil::SemanticDebugScope variables;
for (auto const& scope: _table.scopes() | ranges::views::values)
if (scope)
variables.variableDefinitions += scope->variableDefinitions;
return programContext(variables, resources(_table));
}

langutil::SemanticDebugDataTable ethdebug::semanticDebugDataTable(
ContractDefinition const& _contract,
std::map<std::string, unsigned> const& _sourceIndices
Expand Down
11 changes: 11 additions & 0 deletions libsolidity/interface/Ethdebug.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ std::optional<langutil::ethdebug::schema::program::Context> programContext(
Resources const& _resources
);

/// The resources @a _table carries: its type documents and pointer templates.
Resources resources(langutil::SemanticDebugDataTable const& _table);

/// The program-level context of the variables of all scope records of
/// @a _table, as programContext() selects them: those whose pointer is closed,
/// which are the contract-level ones. For Yul input, whose side table comes
/// from a sidecar rather than from the contract it was generated from.
std::optional<langutil::ethdebug::schema::program::Context> programContext(
langutil::SemanticDebugDataTable const& _table
);

/// The semantic debug info side table of @a _contract, as specified in
/// docs/compiler-guide/ethdebug_internal_debug_info.rst, together with its
/// resources(). It holds the scope record of the contract, with the state
Expand Down
Loading
Loading