diff --git a/evmcc/test/jump/jumpi_at_the_end.evm b/evmcc/test/jump/jumpi_at_the_end.evm new file mode 100644 index 0000000000..2d74117615 --- /dev/null +++ b/evmcc/test/jump/jumpi_at_the_end.evm @@ -0,0 +1 @@ +600a6000545d6000536001900380600054600659 diff --git a/evmcc/test/jump/jumpi_at_the_end.lll b/evmcc/test/jump/jumpi_at_the_end.lll new file mode 100644 index 0000000000..263ada6a78 --- /dev/null +++ b/evmcc/test/jump/jumpi_at_the_end.lll @@ -0,0 +1 @@ +(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI) \ No newline at end of file diff --git a/evmcc/test/vmtests/vm_jump.json b/evmcc/test/vmtests/vm_jump.json new file mode 100644 index 0000000000..6b63edeaef --- /dev/null +++ b/evmcc/test/vmtests/vm_jump.json @@ -0,0 +1,41 @@ +{ + "jumpi_at_the_end" : { + "callcreates" : [ ], + "env" : { + "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", + "currentDifficulty" : "256", + "currentGasLimit" : "10000000", + "currentNumber" : "0", + "currentTimestamp" : "1", + "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6" + }, + "exec" : { + "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", + "caller" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)", + "data" : "0x", + "gas" : "1000", + "gasPrice" : "100000000000000", + "origin" : "cd1722f3947def4cf144679da39c4c32bdc35681", + "value" : "1000000000000000000" + }, + "gas" : "895", + "out" : "0x0", + "pre" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)", + "nonce" : "0", + "storage" : {} + } + }, + "post" : { + "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { + "balance" : "1000000000000000000", + "code" : "(asm 10 0 MSTORE JUMPDEST 0 MLOAD 1 SWAP1 SUB DUP1 0 MSTORE 6 JUMPI)", + "nonce" : "0", + "storage" : {} + } + } + } +} diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index befb843e22..c634187534 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -554,16 +554,15 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, case Instruction::ANY_PUSH: { - auto numBytes = static_cast(inst) - static_cast(Instruction::PUSH1) + 1; + const auto numBytes = static_cast(inst) - static_cast(Instruction::PUSH1) + 1; auto value = llvm::APInt(256, 0); - for (decltype(numBytes) i = 0; i < numBytes; ++i) // TODO: Use pc as iterator + for (auto lastPC = currentPC + numBytes; currentPC < lastPC;) { - ++currentPC; value <<= 8; - value |= bytecode[currentPC]; + value |= bytecode[++currentPC]; } - auto c = m_builder.getInt(value); - stack.push(c); + + stack.push(m_builder.getInt(value)); break; } @@ -641,9 +640,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, { auto pairIter = m_directJumpTargets.find(currentPC); if (pairIter != m_directJumpTargets.end()) - { targetBlock = pairIter->second; - } } if (inst == Instruction::JUMP) @@ -656,9 +653,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, m_builder.CreateBr(targetBlock); } else - { m_builder.CreateBr(m_jumpTableBlock->llvm()); - } } else // JUMPI { @@ -667,8 +662,9 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, auto zero = Constant::get(0); auto cond = m_builder.CreateICmpNE(val, zero, "nonzero"); - // Assume the basic blocks are properly ordered: - assert(nextBasicBlock); // FIXME: JUMPI can be last instruction + + if (!nextBasicBlock) // In case JUMPI is the last instruction + nextBasicBlock = m_stopBB; if (targetBlock) { @@ -676,9 +672,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, m_builder.CreateCondBr(cond, targetBlock, nextBasicBlock); } else - { m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), nextBasicBlock); - } } break; diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp index 86c6e8e07c..84aa105fe2 100644 --- a/libevmjit/Memory.cpp +++ b/libevmjit/Memory.cpp @@ -74,7 +74,8 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _ m_builder.SetInsertPoint(resizeBB); // Check gas first auto wordsRequired = m_builder.CreateUDiv(m_builder.CreateAdd(sizeRequired, Constant::get(31)), Constant::get(32), "wordsRequired"); - auto words = m_builder.CreateUDiv(m_builder.CreateAdd(size, Constant::get(31)), Constant::get(32), "words"); + sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeRequired"); + auto words = m_builder.CreateUDiv(size, Constant::get(32), "words"); // size is always 32*k auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords"); _gasMeter.checkMemory(newWords, m_builder); // Resize