From d359afe34b68fb39c9016634674eb1eb106f0d36 Mon Sep 17 00:00:00 2001 From: Christian Date: Tue, 28 Oct 2014 13:28:17 +0100 Subject: [PATCH 1/3] Reverse operators for SIGNEXTEND and bugfix for k > 2**64. --- libevm/VM.h | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libevm/VM.h b/libevm/VM.h index e81ddb475..85a623b71 100644 --- a/libevm/VM.h +++ b/libevm/VM.h @@ -449,16 +449,15 @@ template dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con break; case Instruction::SIGNEXTEND: { - unsigned k = m_stack[m_stack.size() - 2]; - if (k > 31) - m_stack[m_stack.size() - 2] = m_stack.back(); - else + if (m_stack.back() < 31) { - u256 b = m_stack.back(); - if ((b >> (k * 8)) & 0x80) - for (int i = 31; i > k; --i) - b |= (u256(0xff) << i); - m_stack[m_stack.size() - 2] = b; + unsigned const testBit(m_stack.back() * 8 + 7); + u256& number = m_stack[m_stack.size() - 2]; + u256 mask = ((u256(1) << testBit) - 1); + if (boost::multiprecision::bit_test(number, testBit)) + number |= ~mask; + else + number &= mask; } m_stack.pop_back(); break; From 0baf92d52e4eb311836c40a44db612afa5eda1ff Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 29 Oct 2014 12:59:06 +0100 Subject: [PATCH 2/3] Parser fix: Consume break and continue. --- libsolidity/Parser.cpp | 2 ++ test/solidityParser.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libsolidity/Parser.cpp b/libsolidity/Parser.cpp index 1ea413ee9..44f0a54ad 100644 --- a/libsolidity/Parser.cpp +++ b/libsolidity/Parser.cpp @@ -266,9 +266,11 @@ ASTPointer Parser::parseStatement() // starting from here, all statements must be terminated by a semicolon case Token::CONTINUE: statement = ASTNodeFactory(*this).createNode(); + m_scanner->next(); break; case Token::BREAK: statement = ASTNodeFactory(*this).createNode(); + m_scanner->next(); break; case Token::RETURN: { diff --git a/test/solidityParser.cpp b/test/solidityParser.cpp index 025cd74d1..701a6e76c 100644 --- a/test/solidityParser.cpp +++ b/test/solidityParser.cpp @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(while_loop) { char const* text = "contract test {\n" " function fun(uint256 a) {\n" - " uint256 x = (1 + 4).member(++67) || true;\n" + " while (true) { uint256 x = 1; break; continue; } x = 9;\n" " }\n" "}\n"; BOOST_CHECK_NO_THROW(parseText(text)); From 1d3b26617abe72cc422e2a79a414e8e213b75a2d Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 29 Oct 2014 00:13:26 +0100 Subject: [PATCH 3/3] Bugfix: Tag takes one byte (for JUMPDEST) --- liblll/Assembly.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/liblll/Assembly.cpp b/liblll/Assembly.cpp index 5b10138d1..7ad84682f 100644 --- a/liblll/Assembly.cpp +++ b/liblll/Assembly.cpp @@ -54,6 +54,7 @@ unsigned Assembly::bytesRequired() const switch (i.m_type) { case Operation: + case Tag: // 1 byte for the JUMPDEST ret++; break; case PushString: @@ -69,7 +70,6 @@ unsigned Assembly::bytesRequired() const case PushData: case PushSub: ret += 1 + br; - case Tag:; default:; } if (dev::bytesRequired(ret) <= br)