Browse Source

Merge branch 'develop' of github.com:/ethereum/cpp-ethereum into develop

cl-refactor
Gav Wood 10 years ago
parent
commit
cd9ac5fc22
  1. 2
      evmjit/libevmjit/Utils.h
  2. 11
      libsolidity/AST.cpp
  3. 18
      libsolidity/AST.h
  4. 8
      libsolidity/Parser.cpp
  5. 6
      libsolidity/Token.h
  6. 30
      libsolidity/Types.cpp
  7. 13
      mix/ClientModel.cpp
  8. 9
      mix/ClientModel.h
  9. 3
      mix/MixClient.cpp
  10. 26
      mix/qml/DebugInfoList.qml
  11. 306
      mix/qml/Debugger.qml
  12. 3
      mix/qml/WebPreview.qml
  13. 7
      mix/qml/js/Debugger.js
  14. 1
      mix/qml/js/ProjectModel.js
  15. 2
      mix/qml/main.qml
  16. 70
      test/SolidityExpressionCompiler.cpp
  17. 19
      test/SolidityParser.cpp
  18. 9
      test/SolidityScanner.cpp

2
evmjit/libevmjit/Utils.h

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <iostream>
#include "Common.h" #include "Common.h"
namespace dev namespace dev

11
libsolidity/AST.cpp

@ -594,6 +594,17 @@ void ElementaryTypeNameExpression::checkTypeRequirements()
m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken)); m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
} }
Literal::Literal(Location const& _location, Token::Value _token,
ASTPointer<ASTString> const& _value,
Token::Value _sub):
PrimaryExpression(_location), m_token(_token), m_value(_value)
{
if (Token::isEtherSubdenomination(_sub))
m_subDenomination = static_cast<Literal::SubDenomination>(_sub);
else
m_subDenomination = Literal::SubDenomination::None;
}
void Literal::checkTypeRequirements() void Literal::checkTypeRequirements()
{ {
m_type = Type::forLiteral(*this); m_type = Type::forLiteral(*this);

18
libsolidity/AST.h

@ -1112,13 +1112,22 @@ private:
}; };
/** /**
* A literal string or number. @see Type::literalToBigEndian is used to actually parse its value. * A literal string or number. @see ExpressionCompiler::endVisit() is used to actually parse its value.
*/ */
class Literal: public PrimaryExpression class Literal: public PrimaryExpression
{ {
public: public:
Literal(Location const& _location, Token::Value _token, ASTPointer<ASTString> const& _value): enum class SubDenomination
PrimaryExpression(_location), m_token(_token), m_value(_value) {} {
None = Token::ILLEGAL,
Wei = Token::SubWei,
Szabo = Token::SubSzabo,
Finney = Token::SubFinney,
Ether = Token::SubEther
};
Literal(Location const& _location, Token::Value _token,
ASTPointer<ASTString> const& _value,
Token::Value _sub = Token::ILLEGAL);
virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override; virtual void accept(ASTConstVisitor& _visitor) const override;
virtual void checkTypeRequirements() override; virtual void checkTypeRequirements() override;
@ -1127,9 +1136,12 @@ public:
/// @returns the non-parsed value of the literal /// @returns the non-parsed value of the literal
ASTString const& getValue() const { return *m_value; } ASTString const& getValue() const { return *m_value; }
SubDenomination getSubDenomination() const { return m_subDenomination; }
private: private:
Token::Value m_token; Token::Value m_token;
ASTPointer<ASTString> m_value; ASTPointer<ASTString> m_value;
SubDenomination m_subDenomination;
}; };
/// @} /// @}

8
libsolidity/Parser.cpp

@ -180,7 +180,7 @@ ASTPointer<InheritanceSpecifier> Parser::parseInheritanceSpecifier()
Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token) Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
{ {
Declaration::Visibility visibility; Declaration::Visibility visibility = Declaration::Visibility::DEFAULT;
if (_token == Token::PUBLIC) if (_token == Token::PUBLIC)
visibility = Declaration::Visibility::PUBLIC; visibility = Declaration::Visibility::PUBLIC;
else if (_token == Token::PROTECTED) else if (_token == Token::PROTECTED)
@ -684,6 +684,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
ASTNodeFactory nodeFactory(*this); ASTNodeFactory nodeFactory(*this);
Token::Value token = m_scanner->getCurrentToken(); Token::Value token = m_scanner->getCurrentToken();
ASTPointer<Expression> expression; ASTPointer<Expression> expression;
Token::Value nextToken = Token::ILLEGAL;
switch (token) switch (token)
{ {
case Token::TRUE_LITERAL: case Token::TRUE_LITERAL:
@ -691,9 +692,12 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance()); expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance());
break; break;
case Token::NUMBER: case Token::NUMBER:
nextToken = m_scanner->peekNextToken();
case Token::STRING_LITERAL: case Token::STRING_LITERAL:
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();
expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance()); expression = nodeFactory.createNode<Literal>(token, getLiteralAndAdvance(), nextToken);
if (Token::isEtherSubdenomination(nextToken))
m_scanner->next();
break; break;
case Token::IDENTIFIER: case Token::IDENTIFIER:
nodeFactory.markEndPosition(); nodeFactory.markEndPosition();

6
libsolidity/Token.h

@ -174,6 +174,11 @@ namespace solidity
K(WHILE, "while", 0) \ K(WHILE, "while", 0) \
\ \
\ \
/* Ether subdenominations */ \
K(SubWei, "wei", 0) \
K(SubSzabo, "szabo", 0) \
K(SubFinney, "finney", 0) \
K(SubEther, "ether", 0) \
/* type keywords, keep them in this order, keep int as first keyword /* type keywords, keep them in this order, keep int as first keyword
* the implementation in Types.cpp has to be synced to this here * the implementation in Types.cpp has to be synced to this here
* TODO more to be added */ \ * TODO more to be added */ \
@ -378,6 +383,7 @@ public:
static bool isCountOp(Value op) { return op == INC || op == DEC; } static bool isCountOp(Value op) { return op == INC || op == DEC; }
static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); } static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); }
static bool isVisibilitySpecifier(Value op) { return op == PUBLIC || op == PRIVATE || op == PROTECTED; } static bool isVisibilitySpecifier(Value op) { return op == PUBLIC || op == PRIVATE || op == PROTECTED; }
static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == Token::SubEther; }
// Returns a string corresponding to the JS token string // Returns a string corresponding to the JS token string
// (.e., "<" for the token LT) or NULL if the token doesn't // (.e., "<" for the token LT) or NULL if the token doesn't

30
libsolidity/Types.cpp

@ -326,15 +326,39 @@ string IntegerConstantType::toString() const
return "int_const " + m_value.str(); return "int_const " + m_value.str();
} }
u256 IntegerConstantType::literalValue(Literal const*) const u256 IntegerConstantType::literalValue(Literal const* _literal) const
{ {
u256 value;
// we ignore the literal and hope that the type was correctly determined // we ignore the literal and hope that the type was correctly determined
solAssert(m_value <= u256(-1), "Integer constant too large."); solAssert(m_value <= u256(-1), "Integer constant too large.");
solAssert(m_value >= -(bigint(1) << 255), "Integer constant too small."); solAssert(m_value >= -(bigint(1) << 255), "Integer constant too small.");
if (m_value >= 0) if (m_value >= 0)
return u256(m_value); value = u256(m_value);
else else
return s2u(s256(m_value)); value = s2u(s256(m_value));
if (_literal)
{
Literal::SubDenomination sub =_literal->getSubDenomination();
switch(sub)
{
case Literal::SubDenomination::Wei:
case Literal::SubDenomination::None:
break;
case Literal::SubDenomination::Szabo:
value *= u256(1000000000000);
break;
case Literal::SubDenomination::Finney:
value *= u256(1000000000000000);
break;
case Literal::SubDenomination::Ether:
value *= u256(1000000000000000000);
break;
}
}
return value;
} }
shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const

13
mix/ClientModel.cpp

@ -113,24 +113,27 @@ QString ClientModel::apiCall(QString const& _message)
void ClientModel::mine() void ClientModel::mine()
{ {
if (m_running) if (m_running || m_mining)
BOOST_THROW_EXCEPTION(ExecutionStateException()); BOOST_THROW_EXCEPTION(ExecutionStateException());
m_running = true; m_mining = true;
emit runStarted(); emit miningStarted();
emit runStateChanged(); emit miningStateChanged();
QtConcurrent::run([=]() QtConcurrent::run([=]()
{ {
try try
{ {
m_client->mine(); m_client->mine();
newBlock(); newBlock();
m_mining = false;
emit miningComplete();
} }
catch (...) catch (...)
{ {
m_mining = false;
std::cerr << boost::current_exception_diagnostic_information(); std::cerr << boost::current_exception_diagnostic_information();
emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information())); emit runFailed(QString::fromStdString(boost::current_exception_diagnostic_information()));
} }
m_running = false; emit miningStateChanged();
}); });
} }

9
mix/ClientModel.h

@ -114,6 +114,8 @@ public:
~ClientModel(); ~ClientModel();
/// @returns true if currently executing contract code /// @returns true if currently executing contract code
Q_PROPERTY(bool running MEMBER m_running NOTIFY runStateChanged) Q_PROPERTY(bool running MEMBER m_running NOTIFY runStateChanged)
/// @returns true if currently mining
Q_PROPERTY(bool mining MEMBER m_mining NOTIFY miningStateChanged)
/// @returns address of the last executed contract /// @returns address of the last executed contract
Q_PROPERTY(QString contractAddress READ contractAddress NOTIFY contractAddressChanged) Q_PROPERTY(QString contractAddress READ contractAddress NOTIFY contractAddressChanged)
/// ethereum.js RPC request entry point /// ethereum.js RPC request entry point
@ -144,6 +146,12 @@ signals:
void runStarted(); void runStarted();
/// Transaction execution completed successfully /// Transaction execution completed successfully
void runComplete(); void runComplete();
/// Mining has started
void miningStarted();
/// Mined a new block
void miningComplete();
/// Mining stopped or started
void miningStateChanged();
/// Transaction execution completed with error /// Transaction execution completed with error
/// @param _message Error message /// @param _message Error message
void runFailed(QString const& _message); void runFailed(QString const& _message);
@ -174,6 +182,7 @@ private:
AppContext* m_context; AppContext* m_context;
std::atomic<bool> m_running; std::atomic<bool> m_running;
std::atomic<bool> m_mining;
std::unique_ptr<MixClient> m_client; std::unique_ptr<MixClient> m_client;
std::unique_ptr<RpcConnector> m_rpcConnector; std::unique_ptr<RpcConnector> m_rpcConnector;
std::unique_ptr<Web3Server> m_web3Server; std::unique_ptr<Web3Server> m_web3Server;

3
mix/MixClient.cpp

@ -91,6 +91,7 @@ void MixClient::resetState(u256 _balance)
m_state.sync(bc()); m_state.sync(bc());
m_startState = m_state; m_startState = m_state;
m_pendingExecutions.clear(); m_pendingExecutions.clear();
m_executions.clear();
} }
void MixClient::executeTransaction(Transaction const& _t, State& _state) void MixClient::executeTransaction(Transaction const& _t, State& _state)
@ -215,7 +216,7 @@ ExecutionResult const& MixClient::execution(unsigned _block, unsigned _transacti
{ {
if (_block == bc().number() + 1) if (_block == bc().number() + 1)
return m_pendingExecutions.at(_transaction); return m_pendingExecutions.at(_transaction);
return m_executions.at(_block).at(_transaction); return m_executions.at(_block - 1).at(_transaction);
} }
ExecutionResult const& MixClient::lastExecution() const ExecutionResult const& MixClient::lastExecution() const

26
mix/qml/DebugInfoList.qml

@ -4,14 +4,19 @@ import QtQuick.Layouts 1.0
import QtQuick.Controls.Styles 1.1 import QtQuick.Controls.Styles 1.1
ColumnLayout { ColumnLayout {
id: root
property string title property string title
property variant listModel; property variant listModel;
property bool collapsible; property bool collapsible;
property bool enableSelection;
property real storedHeight;
property Component itemDelegate property Component itemDelegate
signal rowActivated(int index)
spacing: 0 spacing: 0
function collapse() function collapse()
{ {
storedHeight = childrenRect.height;
storageContainer.state = "collapsed"; storageContainer.state = "collapsed";
} }
@ -32,7 +37,9 @@ ColumnLayout {
Image { Image {
source: "qrc:/qml/img/opentriangleindicator.png" source: "qrc:/qml/img/opentriangleindicator.png"
width: 15 width: 15
height: 15
sourceSize.width: 15 sourceSize.width: 15
sourceSize.height: 15
id: storageImgArrow id: storageImgArrow
} }
@ -53,16 +60,20 @@ ColumnLayout {
if (storageContainer.state == "collapsed") if (storageContainer.state == "collapsed")
{ {
storageContainer.state = ""; storageContainer.state = "";
storageContainer.parent.parent.height = storageContainer.parent.parent.Layout.maximumHeight; storageContainer.parent.parent.height = storedHeight;
} }
else else
{
storedHeight = root.childrenRect.height;
storageContainer.state = "collapsed"; storageContainer.state = "collapsed";
}
} }
} }
} }
} }
Rectangle Rectangle
{ {
id: storageContainer
border.width: 3 border.width: 3
border.color: "#deddd9" border.color: "#deddd9"
Layout.fillWidth: true Layout.fillWidth: true
@ -80,18 +91,23 @@ ColumnLayout {
} }
} }
] ]
id: storageContainer TableView {
ListView {
clip: true; clip: true;
alternatingRowColors: false
anchors.top: parent.top anchors.top: parent.top
anchors.left: parent.left anchors.left: parent.left
anchors.topMargin: 3 anchors.topMargin: 3
anchors.leftMargin: 3 anchors.leftMargin: 3
width: parent.width - 3 width: parent.width - 3
height: parent.height - 6 height: parent.height - 6
id: storageList
model: listModel model: listModel
delegate: itemDelegate selectionMode: enableSelection ? SelectionMode.SingleSelection : SelectionMode.NoSelection
headerDelegate: null
itemDelegate: root.itemDelegate
TableViewColumn {
role: "modelData"
width: parent.width
}
} }
} }
} }

306
mix/qml/Debugger.qml

@ -55,6 +55,15 @@ Rectangle {
onCompilationComplete: update(null, false); onCompilationComplete: update(null, false);
} }
Settings {
id: splitSettings
property alias transactionLogHeight: transactionLog.height
property alias callStackHeight: callStackRect.height
property alias storageHeightSettings: storageRect.height
property alias memoryDumpHeightSettings: memoryRect.height
property alias callDataHeightSettings: callDataRect.height
}
Rectangle Rectangle
{ {
visible: false; visible: false;
@ -104,49 +113,60 @@ Rectangle {
} }
} }
Flickable { ScrollView {
property int firstColumnWidth: 180
property int secondColumnWidth: 250
id: debugScrollArea id: debugScrollArea
flickableDirection: Flickable.VerticalFlick
anchors.fill: parent anchors.fill: parent
contentHeight: 4000
contentWidth: parent.width SplitView
Rectangle
{ {
color: "transparent" property int sideMargin: 10
anchors.fill: parent id: machineStates
ColumnLayout anchors.top: parent.top
{ anchors.topMargin: 15
property int sideMargin: 10 anchors.left: parent.left;
id: machineStates anchors.leftMargin: machineStates.sideMargin
anchors.top: parent.top width: debugScrollArea.width - machineStates.sideMargin * 2 - 20;
anchors.topMargin: 15 orientation: Qt.Vertical
anchors.left: parent.left; handleDelegate: Rectangle {
anchors.leftMargin: machineStates.sideMargin height: machineStates.sideMargin
anchors.right: parent.right; color: "transparent"
anchors.rightMargin: machineStates.sideMargin }
anchors.fill: parent
function updateHeight() {
machineStates.height = transactionLog.childrenRect.height + buttonRow.childrenRect.height + assemblyCodeRow.childrenRect.height +
callStackRect.childrenRect.height + storageRect.childrenRect.height + memoryRect.childrenRect.height + callDataRect.childrenRect.height + 120;
}
Component.onCompleted: updateHeight();
TransactionLog {
id: transactionLog
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.minimumHeight: 60
height: 250
}
TransactionLog { ColumnLayout {
Layout.fillWidth: true
height: 250 Layout.fillWidth: true
} Layout.fillHeight: true
id: statesLayout
spacing: machineStates.sideMargin
RowLayout { Rectangle {
// step button + slider // step button + slider
id: buttonRow id: buttonRow
spacing: machineStates.sideMargin
height: 27 height: 27
Layout.fillWidth: true Layout.fillWidth: true
color: "transparent"
Rectangle Rectangle {
{ anchors.top: parent.top
height: parent.height anchors.bottom: parent.bottom
anchors.left: parent.left
color: "transparent" color: "transparent"
width: debugScrollArea.firstColumnWidth width: stateListContainer.width
RowLayout { RowLayout {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
id: jumpButtons id: jumpButtons
@ -226,9 +246,11 @@ Rectangle {
} }
Rectangle { Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
width: debugInfoContainer.width
color: "transparent" color: "transparent"
Layout.fillWidth: true
height: parent.height
Slider { Slider {
id: statesSlider id: statesSlider
anchors.fill: parent anchors.fill: parent
@ -255,83 +277,99 @@ Rectangle {
} }
} }
RowLayout { Rectangle {
// Assembly code // Assembly code
id: assemblyCodeRow id: assemblyCodeRow
Layout.fillWidth: true Layout.fillWidth: true
height: 405 height: 405
implicitHeight: 405 implicitHeight: 405
spacing: machineStates.sideMargin color: "transparent"
Rectangle Rectangle
{ {
id: stateListContainer id: stateListContainer
width: debugScrollArea.firstColumnWidth anchors.top : parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
width: parent.width * 0.4
height: parent.height height: parent.height
border.width: 3 border.width: 3
border.color: "#deddd9" border.color: "#deddd9"
color: "white" color: "white"
anchors.top: parent.top TableView {
ListView { id: statesList
anchors.fill: parent anchors.fill: parent
anchors.leftMargin: 3 anchors.leftMargin: 3
anchors.rightMargin: 3 anchors.rightMargin: 3
anchors.topMargin: 3 anchors.topMargin: 3
anchors.bottomMargin: 3 anchors.bottomMargin: 3
clip: true clip: true
id: statesList headerDelegate: null
delegate: renderDelegate itemDelegate: renderDelegate
highlight: highlightBar
//highlightFollowsCurrentItem: false
model: ListModel {} model: ListModel {}
TableViewColumn {
role: "line"
width: parent.width - 10
}
} }
Component { Component {
id: highlightBar id: highlightBar
Rectangle { Rectangle {
radius: 4 radius: 4
height: statesList.currentItem.height anchors.fill: parent
width: statesList.currentItem.width;
y: statesList.currentItem.y y: statesList.currentItem.y
color: "#4A90E2" color: "#4A90E2"
//Behavior on y {
// PropertyAnimation { properties: "y"; easing.type: Easing.InOutQuad; duration: 50}
//}
} }
} }
Component { Component {
id: renderDelegate id: renderDelegate
RowLayout { Item {
id: wrapperItem Rectangle {
height: 20 radius: 4
width: parent.width anchors.fill: parent
spacing: 5 color: "#4A90E2"
Text { visible: styleData.selected;
anchors.left: parent.left
anchors.leftMargin: 10
width: 15
color: "#b2b3ae"
text: line.split(' ')[0]
font.family: "monospace"
font.pointSize: 9
id: id
wrapMode: Text.NoWrap
} }
Text {
wrapMode: Text.NoWrap RowLayout {
color: parent.ListView.isCurrentItem ? "white" : "black" id: wrapperItem
font.family: "monospace" anchors.fill: parent
text: line.replace(line.split(' ')[0], '') spacing: 5
anchors.left: id.right
font.pointSize: 9
Text {
anchors.left: parent.left
anchors.leftMargin: 10
width: 15
color: "#b2b3ae"
text: styleData.value.split(' ')[0]
font.family: "monospace"
font.pointSize: 9
wrapMode: Text.NoWrap
id: id
}
Text {
anchors.left: id.right;
wrapMode: Text.NoWrap
color: styleData.selected ? "white" : "black"
font.family: "monospace"
text: styleData.value.replace(styleData.value.split(' ')[0], '')
font.pointSize: 9
}
} }
} }
} }
} }
Rectangle { Rectangle {
Layout.fillWidth: true id: debugInfoContainer
width: parent.width * 0.6 - machineStates.sideMargin
anchors.top : parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
height: parent.height //- 2 * stateListContainer.border.width height: parent.height //- 2 * stateListContainer.border.width
color: "transparent" color: "transparent"
ColumnLayout ColumnLayout
@ -372,7 +410,7 @@ Rectangle {
title : qsTr("Stack") title : qsTr("Stack")
itemDelegate: Item { itemDelegate: Item {
id: renderedItem id: renderedItem
height: 25 //height: 25
width: parent.width width: parent.width
RowLayout RowLayout
{ {
@ -391,7 +429,7 @@ Rectangle {
anchors.leftMargin: 5 anchors.leftMargin: 5
font.family: "monospace" font.family: "monospace"
color: "#4a4a4a" color: "#4a4a4a"
text: model.index; text: styleData.row;
font.pointSize: 9 font.pointSize: 9
} }
} }
@ -402,7 +440,6 @@ Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumWidth: 15 Layout.minimumWidth: 15
Layout.preferredWidth: 15 Layout.preferredWidth: 15
Layout.maximumWidth: 60
Layout.minimumHeight: parent.height Layout.minimumHeight: parent.height
Text { Text {
anchors.left: parent.left anchors.left: parent.left
@ -410,7 +447,7 @@ Rectangle {
font.family: "monospace" font.family: "monospace"
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: "#4a4a4a" color: "#4a4a4a"
text: modelData text: styleData.value
font.pointSize: 9 font.pointSize: 9
} }
} }
@ -434,33 +471,87 @@ Rectangle {
id: splitInfoList id: splitInfoList
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
Settings {
id: splitSettings
property alias storageHeightSettings: storageRect.height
property alias memoryDumpHeightSettings: memoryRect.height
property alias callDataHeightSettings: callDataRect.height
}
orientation: Qt.Vertical orientation: Qt.Vertical
width: debugPanel.width - 2 * machineStates.sideMargin
Rectangle Rectangle
{ {
id: callStackRect; id: callStackRect;
color: "transparent" color: "transparent"
height: 120 Layout.minimumHeight: 25
width: parent.width Layout.maximumHeight: 800
Layout.minimumHeight: 120 onHeightChanged: machineStates.updateHeight();
Layout.maximumHeight: 400 DebugInfoList
CallStack { {
anchors.fill: parent
id: callStack id: callStack
onFrameActivated: Debugger.displayFrame(index); collapsible: true
anchors.fill: parent
title : qsTr("Call Stack")
enableSelection: true
onRowActivated: Debugger.displayFrame(index);
itemDelegate:
Item {
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "#4A90E2"
visible: styleData.selected;
}
RowLayout
{
id: row
anchors.fill: parent
Rectangle
{
color: "#f7f7f7"
Layout.fillWidth: true
Layout.minimumWidth: 30
Layout.maximumWidth: 30
Text {
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
font.family: "monospace"
anchors.leftMargin: 5
color: "#4a4a4a"
text: styleData.row;
font.pointSize: 9
width: parent.width - 5
elide: Text.ElideRight
}
}
Rectangle
{
color: "transparent"
Layout.fillWidth: true
Layout.minimumWidth: parent.width - 30
Layout.maximumWidth: parent.width - 30
Text {
anchors.leftMargin: 5
width: parent.width - 5
wrapMode: Text.Wrap
anchors.left: parent.left
font.family: "monospace"
anchors.verticalCenter: parent.verticalCenter
color: "#4a4a4a"
text: styleData.value;
elide: Text.ElideRight
font.pointSize: 9
}
}
}
Rectangle {
anchors.top: row.bottom
width: parent.width;
height: 1;
color: "#cccccc"
anchors.bottom: parent.bottom
}
}
} }
}
}
Rectangle Rectangle
{ {
@ -468,8 +559,8 @@ Rectangle {
color: "transparent" color: "transparent"
width: parent.width width: parent.width
Layout.minimumHeight: 25 Layout.minimumHeight: 25
Layout.maximumHeight: 223 Layout.maximumHeight: 800
height: 25 onHeightChanged: machineStates.updateHeight();
DebugInfoList DebugInfoList
{ {
id: storage id: storage
@ -478,29 +569,24 @@ Rectangle {
title : qsTr("Storage") title : qsTr("Storage")
itemDelegate: itemDelegate:
Item { Item {
height: 27 anchors.fill: parent
width: parent.width;
RowLayout RowLayout
{ {
id: row id: row
width: parent.width anchors.fill: parent
height: 26
Rectangle Rectangle
{ {
color: "#f7f7f7" color: "#f7f7f7"
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumWidth: parent.width / 2 Layout.minimumWidth: parent.width / 2
Layout.preferredWidth: parent.width / 2
Layout.maximumWidth: parent.width / 2 Layout.maximumWidth: parent.width / 2
Layout.minimumHeight: parent.height
Layout.maximumHeight: parent.height
Text { Text {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left anchors.left: parent.left
font.family: "monospace" font.family: "monospace"
anchors.leftMargin: 5 anchors.leftMargin: 5
color: "#4a4a4a" color: "#4a4a4a"
text: modelData.split('\t')[0]; text: styleData.value.split('\t')[0];
font.pointSize: 9 font.pointSize: 9
width: parent.width - 5 width: parent.width - 5
elide: Text.ElideRight elide: Text.ElideRight
@ -511,10 +597,7 @@ Rectangle {
color: "transparent" color: "transparent"
Layout.fillWidth: true Layout.fillWidth: true
Layout.minimumWidth: parent.width / 2 Layout.minimumWidth: parent.width / 2
Layout.preferredWidth: parent.width / 2
Layout.maximumWidth: parent.width / 2 Layout.maximumWidth: parent.width / 2
Layout.minimumHeight: parent.height
Layout.maximumHeight: parent.height
Text { Text {
anchors.leftMargin: 5 anchors.leftMargin: 5
width: parent.width - 5 width: parent.width - 5
@ -523,7 +606,7 @@ Rectangle {
font.family: "monospace" font.family: "monospace"
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
color: "#4a4a4a" color: "#4a4a4a"
text: modelData.split('\t')[1]; text: styleData.value.split('\t')[1];
elide: Text.ElideRight elide: Text.ElideRight
font.pointSize: 9 font.pointSize: 9
} }
@ -545,10 +628,10 @@ Rectangle {
{ {
id: memoryRect; id: memoryRect;
color: "transparent" color: "transparent"
height: 25
width: parent.width width: parent.width
Layout.minimumHeight: 25 Layout.minimumHeight: 25
Layout.maximumHeight: 223 Layout.maximumHeight: 800
onHeightChanged: machineStates.updateHeight();
DebugInfoList { DebugInfoList {
id: memoryDump id: memoryDump
anchors.fill: parent anchors.fill: parent
@ -567,10 +650,10 @@ Rectangle {
{ {
id: callDataRect id: callDataRect
color: "transparent" color: "transparent"
height: 25
width: parent.width width: parent.width
Layout.minimumHeight: 25 Layout.minimumHeight: 25
Layout.maximumHeight: 223 Layout.maximumHeight: 800
onHeightChanged: machineStates.updateHeight();
DebugInfoList { DebugInfoList {
id: callDataDump id: callDataDump
anchors.fill: parent anchors.fill: parent
@ -586,8 +669,9 @@ Rectangle {
} }
Rectangle Rectangle
{ {
id: bottomRect;
width: parent.width width: parent.width
Layout.minimumHeight: 25 Layout.minimumHeight: 20
color: "transparent" color: "transparent"
} }
} }

3
mix/qml/WebPreview.qml

@ -114,7 +114,8 @@ Item {
onClientConnected: { onClientConnected: {
//filter polling spam //filter polling spam
//TODO: do it properly //TODO: do it properly
var log = _request.content.indexOf("eth_changed") < 0; //var log = _request.content.indexOf("eth_changed") < 0;
var log = true;
if (log) if (log)
console.log(_request.content); console.log(_request.content);
var response = clientModel.apiCall(_request.content); var response = clientModel.apiCall(_request.content);

7
mix/qml/js/Debugger.js

@ -107,7 +107,7 @@ function select(stateIndex)
callStackData.push(address); callStackData.push(address);
} }
callStackData.push(debugData.states[0].address); callStackData.push(debugData.states[0].address);
callStack.model = callStackData; callStack.listModel = callStackData;
} }
function codeStr(stateIndex) function codeStr(stateIndex)
@ -118,8 +118,9 @@ function codeStr(stateIndex)
function highlightSelection(index) function highlightSelection(index)
{ {
statesList.currentIndex = index; statesList.positionViewAtRow(index, ListView.Center);
statesList.positionViewAtIndex(index, ListView.Center); statesList.selection.clear();
statesList.selection.select(index);
} }
function completeCtxInformation(state) function completeCtxInformation(state)

1
mix/qml/js/ProjectModel.js

@ -153,6 +153,7 @@ function doCloseProject() {
console.log("closing project"); console.log("closing project");
projectListModel.clear(); projectListModel.clear();
projectPath = ""; projectPath = "";
currentDocumentId = "";
projectClosed(); projectClosed();
} }

2
mix/qml/main.qml

@ -88,7 +88,7 @@ ApplicationWindow {
text: qsTr("Mine") text: qsTr("Mine")
shortcut: "Ctrl+M" shortcut: "Ctrl+M"
onTriggered: clientModel.mine(); onTriggered: clientModel.mine();
enabled: codeModel.hasContract && !clientModel.running enabled: codeModel.hasContract && !clientModel.running &&!clientModel.mining
} }
Connections { Connections {

70
test/SolidityExpressionCompiler.cpp

@ -91,7 +91,15 @@ bytes compileFirstExpression(const string& _sourceCode, vector<vector<string>> _
{ {
Parser parser; Parser parser;
ASTPointer<SourceUnit> sourceUnit; ASTPointer<SourceUnit> sourceUnit;
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)))); try
{
sourceUnit = parser.parse(make_shared<Scanner>(CharStream(_sourceCode)));
}
catch(boost::exception const& _e)
{
auto msg = std::string("Parsing source code failed with: \n") + boost::diagnostic_information(_e);
BOOST_FAIL(msg);
}
vector<Declaration const*> declarations; vector<Declaration const*> declarations;
declarations.reserve(_globalDeclarations.size() + 1); declarations.reserve(_globalDeclarations.size() + 1);
@ -177,6 +185,66 @@ BOOST_AUTO_TEST_CASE(int_literal)
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end()); BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
} }
BOOST_AUTO_TEST_CASE(int_with_wei_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
function test ()
{
var x = 1 wei;
}
})";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH1), 0x1});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
BOOST_AUTO_TEST_CASE(int_with_szabo_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
function test ()
{
var x = 1 szabo;
}
})";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH5), 0xe8, 0xd4, 0xa5, 0x10, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
BOOST_AUTO_TEST_CASE(int_with_finney_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
function test ()
{
var x = 1 finney;
}
})";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH7), 0x3, 0x8d, 0x7e, 0xa4, 0xc6, 0x80, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
BOOST_AUTO_TEST_CASE(int_with_ether_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
function test ()
{
var x = 1 ether;
}
})";
bytes code = compileFirstExpression(sourceCode);
bytes expectation({byte(eth::Instruction::PUSH8), 0xd, 0xe0, 0xb6, 0xb3, 0xa7, 0x64, 0x00, 0x00});
BOOST_CHECK_EQUAL_COLLECTIONS(code.begin(), code.end(), expectation.begin(), expectation.end());
}
BOOST_AUTO_TEST_CASE(comparison) BOOST_AUTO_TEST_CASE(comparison)
{ {
char const* sourceCode = "contract test {\n" char const* sourceCode = "contract test {\n"

19
test/SolidityParser.cpp

@ -660,6 +660,25 @@ BOOST_AUTO_TEST_CASE(multiple_visibility_specifiers)
BOOST_CHECK_THROW(parseText(text), ParserError); BOOST_CHECK_THROW(parseText(text), ParserError);
} }
BOOST_AUTO_TEST_CASE(literal_constants_with_ether_subdenominations)
{
char const* text = R"(
contract c {
function c ()
{
a = 1 wei;
b = 2 szabo;
c = 3 finney;
b = 4 ether;
}
uint256 a;
uint256 b;
uint256 c;
uint256 d;
})";
BOOST_CHECK_NO_THROW(parseTextExplainError(text));
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

9
test/SolidityScanner.cpp

@ -255,6 +255,15 @@ BOOST_AUTO_TEST_CASE(comments_mixed_in_sequence)
BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "documentation comment "); BOOST_CHECK_EQUAL(scanner.getCurrentCommentLiteral(), "documentation comment ");
} }
BOOST_AUTO_TEST_CASE(ether_subdenominations)
{
Scanner scanner(CharStream("wei szabo finney ether"));
BOOST_CHECK_EQUAL(scanner.getCurrentToken(), Token::SubWei);
BOOST_CHECK_EQUAL(scanner.next(), Token::SubSzabo);
BOOST_CHECK_EQUAL(scanner.next(), Token::SubFinney);
BOOST_CHECK_EQUAL(scanner.next(), Token::SubEther);
}
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()
} }

Loading…
Cancel
Save