diff --git a/alethzero/Main.ui b/alethzero/Main.ui index a01ac7856..f5b52c309 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -185,6 +185,7 @@ + @@ -563,7 +564,7 @@ - Qt::NoFocus + Qt::ClickFocus QFrame::NoFrame @@ -571,6 +572,9 @@ 0 + + true + @@ -1664,6 +1668,14 @@ font-size: 14pt &Refresh + + + true + + + &Enable LLL &Optimizer + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 6c18d39bd..a4fc22a43 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -332,6 +332,12 @@ void Main::on_forceMining_triggered() m_client->setForceMining(ui->forceMining->isChecked()); } +void Main::on_enableOptimizer_triggered() +{ + m_enableOptimizer = ui->enableOptimizer->isChecked(); + on_data_textChanged(); +} + void Main::load(QString _s) { QFile fin(_s); @@ -523,6 +529,7 @@ void Main::writeSettings() s.setValue("paranoia", ui->paranoia->isChecked()); s.setValue("showAll", ui->showAll->isChecked()); s.setValue("showAllAccounts", ui->showAllAccounts->isChecked()); + s.setValue("enableOptimizer", m_enableOptimizer); s.setValue("clientName", ui->clientName->text()); s.setValue("idealPeers", ui->idealPeers->value()); s.setValue("port", ui->port->value()); @@ -570,6 +577,8 @@ void Main::readSettings(bool _skipGeometry) ui->paranoia->setChecked(s.value("paranoia", false).toBool()); ui->showAll->setChecked(s.value("showAll", false).toBool()); ui->showAllAccounts->setChecked(s.value("showAllAccounts", false).toBool()); + m_enableOptimizer = s.value("enableOptimizer", true).toBool(); + ui->enableOptimizer->setChecked(m_enableOptimizer); ui->clientName->setText(s.value("clientName", "").toString()); ui->idealPeers->setValue(s.value("idealPeers", ui->idealPeers->value()).toInt()); ui->port->setValue(s.value("port", ui->port->value()).toInt()); @@ -1302,9 +1311,7 @@ void Main::on_data_textChanged() } else { - auto asmcode = eth::compileLLLToAsm(src, false); - auto asmcodeopt = eth::compileLLLToAsm(ui->data->toPlainText().toStdString(), true); - m_data = eth::compileLLL(ui->data->toPlainText().toStdString(), true, &errors); + m_data = eth::compileLLL(src, m_enableOptimizer, &errors); if (errors.size()) { try @@ -1319,7 +1326,15 @@ void Main::on_data_textChanged() } } else - lll = "

Opt

" + QString::fromStdString(asmcodeopt).toHtmlEscaped() + "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; + { + auto asmcode = eth::compileLLLToAsm(src, false); + lll = "

Pre

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
"; + if (m_enableOptimizer) + { + asmcode = eth::compileLLLToAsm(src, true); + lll = "

Opt

" + QString::fromStdString(asmcode).toHtmlEscaped() + "
" + lll; + } + } } QString errs; if (errors.size()) diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index f54a64053..46cb1843a 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -138,6 +138,7 @@ private slots: void on_debugDumpState_triggered(int _add = 1); void on_debugDumpStatePre_triggered(); void on_refresh_triggered(); + void on_enableOptimizer_triggered(); signals: void poll(); @@ -221,6 +222,7 @@ private: QMap m_pcWarp; QList m_history; std::map m_codes; // and pcWarps + bool m_enableOptimizer = true; QNetworkAccessManager m_webCtrl; diff --git a/libevm/VM.h b/libevm/VM.h index 15f05fd26..f014e2da8 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -241,9 +241,9 @@ template eth::bytesConstRef eth::VM::go(Ext& _ext, OnOpFunc const& _ { require(2); auto base = m_stack.back(); - unsigned expon = (unsigned)m_stack[m_stack.size() - 2]; + auto expon = m_stack[m_stack.size() - 2]; m_stack.pop_back(); - m_stack.back() = boost::multiprecision::pow(base, expon); + m_stack.back() = (u256)boost::multiprecision::powm((bigint)base, (bigint)expon, bigint(2) << 256); break; } case Instruction::NEG: diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp index 78552f3c5..491d3812e 100644 --- a/liblll/Assembly.cpp +++ b/liblll/Assembly.cpp @@ -227,14 +227,14 @@ Assembly& Assembly::optimise(bool _enable) { { Instruction::SUB, [](u256 a, u256 b)->u256{return a - b;} }, { Instruction::DIV, [](u256 a, u256 b)->u256{return a / b;} }, - { Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} }, + { Instruction::SDIV, [](u256 a, u256 b)->u256{return s2u(u2s(a) / u2s(b));} }, { Instruction::MOD, [](u256 a, u256 b)->u256{return a % b;} }, - { Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} }, - { Instruction::EXP, [](u256 a, u256 b)->u256{return boost::multiprecision::pow(a, (unsigned)b);} }, + { Instruction::SMOD, [](u256 a, u256 b)->u256{return s2u(u2s(a) % u2s(b));} }, + { Instruction::EXP, [](u256 a, u256 b)->u256{return (u256)boost::multiprecision::powm((bigint)a, (bigint)b, bigint(2) << 256);} }, { Instruction::LT, [](u256 a, u256 b)->u256{return a < b ? 1 : 0;} }, { Instruction::GT, [](u256 a, u256 b)->u256{return a > b ? 1 : 0;} }, - { Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} }, - { Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} }, + { Instruction::SLT, [](u256 a, u256 b)->u256{return u2s(a) < u2s(b) ? 1 : 0;} }, + { Instruction::SGT, [](u256 a, u256 b)->u256{return u2s(a) > u2s(b) ? 1 : 0;} }, { Instruction::EQ, [](u256 a, u256 b)->u256{return a == b ? 1 : 0;} }, }; map> c_associative =