diff options
author | chriseth <chris@ethereum.org> | 2017-07-03 20:52:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-07-03 20:52:29 +0800 |
commit | 76d3b7c5a160e1f550c710e6850ee6f116142ca1 (patch) | |
tree | 93c96f7073617b4f56c8c355cdc30701aec4818b /liblll/CodeFragment.cpp | |
parent | 78969364608ba60d1654f4d1738886d13112b6cd (diff) | |
parent | 2222ddecf49b5b901f63b9e7449ee76c9f51c47a (diff) | |
download | dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.gz dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.bz2 dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.lz dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.xz dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.tar.zst dexon-solidity-76d3b7c5a160e1f550c710e6850ee6f116142ca1.zip |
Merge pull request #2510 from ethereum/develop
Version 0.4.12
Diffstat (limited to 'liblll/CodeFragment.cpp')
-rw-r--r-- | liblll/CodeFragment.cpp | 62 |
1 files changed, 42 insertions, 20 deletions
diff --git a/liblll/CodeFragment.cpp b/liblll/CodeFragment.cpp index 2b8822a6..56c1e26a 100644 --- a/liblll/CodeFragment.cpp +++ b/liblll/CodeFragment.cpp @@ -171,11 +171,23 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) return string(); }; - auto varAddress = [&](string const& n) + auto varAddress = [&](string const& n, bool createMissing = false) { + if (n.empty()) + error<InvalidName>("Empty variable name not allowed"); auto it = _s.vars.find(n); if (it == _s.vars.end()) - error<InvalidName>(std::string("Symbol not found: ") + s); + { + if (createMissing) + { + // Create new variable + bool ok; + tie(it, ok) = _s.vars.insert(make_pair(n, make_pair(_s.stackSize, 32))); + _s.stackSize += 32; + } + else + error<InvalidName>(std::string("Symbol not found: ") + n); + } return it->second.first; }; @@ -192,7 +204,13 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) { if (_t.size() != 2) error<IncorrectParameterCount>(); - m_asm.append(CodeFragment::compile(contentsString(firstAsString()), _s).m_asm); + string fileName = firstAsString(); + if (fileName.empty()) + error<InvalidName>("Empty file name provided"); + string contents = contentsString(fileName); + if (contents.empty()) + error<InvalidName>(std::string("File not found (or empty): ") + fileName); + m_asm.append(CodeFragment::compile(contents, _s).m_asm); } else if (us == "SET") { @@ -202,7 +220,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) for (auto const& i: _t) if (c++ == 2) m_asm.append(CodeFragment(i, _s, false).m_asm); - m_asm.append((u256)varAddress(firstAsString())); + m_asm.append((u256)varAddress(firstAsString(), true)); m_asm.append(Instruction::MSTORE); } else if (us == "GET") @@ -240,7 +258,11 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) } else if (ii == 2) if (_t.size() == 3) - _s.defs[n] = CodeFragment(i, _s); + { + /// NOTE: some compilers could do the assignment first if this is done in a single line + CodeFragment code = CodeFragment(i, _s); + _s.defs[n] = code; + } else for (auto const& j: i) { @@ -439,15 +461,21 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit()); m_asm.append(code[0].m_asm); - auto pos = m_asm.appendJumpI(); - m_asm.onePath(); + auto mainBranch = m_asm.appendJumpI(); + + /// The else branch. + int startDeposit = m_asm.deposit(); m_asm.append(code[2].m_asm, minDep); auto end = m_asm.appendJump(); - m_asm.otherPath(); - m_asm << pos.tag(); + int deposit = m_asm.deposit(); + m_asm.setDeposit(startDeposit); + + /// The main branch. + m_asm << mainBranch.tag(); m_asm.append(code[1].m_asm, minDep); m_asm << end.tag(); - m_asm.donePaths(); + if (m_asm.deposit() != deposit) + error<InvalidDeposit>(); } else if (us == "WHEN" || us == "UNLESS") { @@ -458,11 +486,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) if (us == "WHEN") m_asm.append(Instruction::ISZERO); auto end = m_asm.appendJumpI(); - m_asm.onePath(); - m_asm.otherPath(); m_asm.append(code[1].m_asm, 0); m_asm << end.tag(); - m_asm.donePaths(); } else if (us == "WHILE" || us == "UNTIL") { @@ -515,8 +540,7 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) requireMaxSize(3); requireDeposit(1, 1); - auto subPush = m_asm.newSub(make_shared<Assembly>(code[0].assembly(ns))); - m_asm.append(m_asm.newPushSubSize(subPush.data())); + auto subPush = m_asm.appendSubroutine(make_shared<Assembly>(code[0].assembly(ns))); m_asm.append(Instruction::DUP1); if (code.size() == 3) { @@ -571,11 +595,9 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s) { for (auto const& i: code) m_asm.append(i.m_asm); - m_asm.popTo(1); - } - else if (us == "PANIC") - { - m_asm.appendJump(m_asm.errorTag()); + // Leave only the last item on stack. + while (m_asm.deposit() > 1) + m_asm.append(Instruction::POP); } else if (us == "BYTECODESIZE") { |