aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.cpp2
-rw-r--r--libjulia/backends/evm/EVMCodeTransform.h5
-rw-r--r--libsolidity/codegen/CompilerUtils.cpp42
-rw-r--r--libsolidity/codegen/CompilerUtils.h6
-rw-r--r--libsolidity/codegen/ExpressionCompiler.cpp4
-rw-r--r--libsolidity/codegen/LValue.cpp6
-rw-r--r--libsolidity/inlineasm/AsmCodeGen.cpp3
-rw-r--r--libsolidity/interface/AssemblyStack.cpp4
8 files changed, 48 insertions, 24 deletions
diff --git a/libjulia/backends/evm/EVMCodeTransform.cpp b/libjulia/backends/evm/EVMCodeTransform.cpp
index 8f12bc25..efbe5647 100644
--- a/libjulia/backends/evm/EVMCodeTransform.cpp
+++ b/libjulia/backends/evm/EVMCodeTransform.cpp
@@ -294,7 +294,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
m_assembly.appendConstant(u256(0));
}
- CodeTransform(m_assembly, m_info, m_evm15, m_identifierAccess, localStackAdjustment, m_context)
+ CodeTransform(m_assembly, m_info, m_julia, m_evm15, m_identifierAccess, localStackAdjustment, m_context)
(_function.body);
{
diff --git a/libjulia/backends/evm/EVMCodeTransform.h b/libjulia/backends/evm/EVMCodeTransform.h
index d09ee87b..cd452c5b 100644
--- a/libjulia/backends/evm/EVMCodeTransform.h
+++ b/libjulia/backends/evm/EVMCodeTransform.h
@@ -48,11 +48,13 @@ public:
CodeTransform(
julia::AbstractAssembly& _assembly,
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
+ bool _julia = false,
bool _evm15 = false,
ExternalIdentifierAccess const& _identifierAccess = ExternalIdentifierAccess()
): CodeTransform(
_assembly,
_analysisInfo,
+ _julia,
_evm15,
_identifierAccess,
_assembly.stackHeight(),
@@ -73,6 +75,7 @@ protected:
CodeTransform(
julia::AbstractAssembly& _assembly,
solidity::assembly::AsmAnalysisInfo& _analysisInfo,
+ bool _julia,
bool _evm15,
ExternalIdentifierAccess const& _identifierAccess,
int _stackAdjustment,
@@ -80,6 +83,7 @@ protected:
):
m_assembly(_assembly),
m_info(_analysisInfo),
+ m_julia(_julia),
m_evm15(_evm15),
m_identifierAccess(_identifierAccess),
m_stackAdjustment(_stackAdjustment),
@@ -130,6 +134,7 @@ private:
julia::AbstractAssembly& m_assembly;
solidity::assembly::AsmAnalysisInfo& m_info;
solidity::assembly::Scope* m_scope = nullptr;
+ bool m_julia = false;
bool m_evm15 = false;
ExternalIdentifierAccess m_identifierAccess;
/// Adjustment between the stack height as determined during the analysis phase
diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp
index a105036f..7067ddd5 100644
--- a/libsolidity/codegen/CompilerUtils.cpp
+++ b/libsolidity/codegen/CompilerUtils.cpp
@@ -353,13 +353,16 @@ void CompilerUtils::splitExternalFunctionType(bool _leftAligned)
// address (right aligned), function identifier (right aligned)
if (_leftAligned)
{
- m_context << Instruction::DUP1 << (u256(1) << (64 + 32)) << Instruction::SWAP1 << Instruction::DIV;
+ m_context << Instruction::DUP1;
+ rightShiftNumberOnStack(64 + 32, false);
// <input> <address>
- m_context << Instruction::SWAP1 << (u256(1) << 64) << Instruction::SWAP1 << Instruction::DIV;
+ m_context << Instruction::SWAP1;
+ rightShiftNumberOnStack(64, false);
}
else
{
- m_context << Instruction::DUP1 << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV;
+ m_context << Instruction::DUP1;
+ rightShiftNumberOnStack(32, false);
m_context << ((u256(1) << 160) - 1) << Instruction::AND << Instruction::SWAP1;
}
m_context << u256(0xffffffffUL) << Instruction::AND;
@@ -371,10 +374,10 @@ void CompilerUtils::combineExternalFunctionType(bool _leftAligned)
m_context << u256(0xffffffffUL) << Instruction::AND << Instruction::SWAP1;
if (!_leftAligned)
m_context << ((u256(1) << 160) - 1) << Instruction::AND;
- m_context << (u256(1) << 32) << Instruction::MUL;
+ leftShiftNumberOnStack(32);
m_context << Instruction::OR;
if (_leftAligned)
- m_context << (u256(1) << 64) << Instruction::MUL;
+ leftShiftNumberOnStack(64);
}
void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function)
@@ -383,11 +386,12 @@ void CompilerUtils::pushCombinedFunctionEntryLabel(Declaration const& _function)
// If there is a runtime context, we have to merge both labels into the same
// stack slot in case we store it in storage.
if (CompilerContext* rtc = m_context.runtimeContext())
+ {
+ leftShiftNumberOnStack(32);
m_context <<
- (u256(1) << 32) <<
- Instruction::MUL <<
rtc->functionEntryLabel(_function).toSubAssemblyTag(m_context.runtimeSub()) <<
Instruction::OR;
+ }
}
void CompilerUtils::convertType(
@@ -425,7 +429,7 @@ void CompilerUtils::convertType(
// conversion from bytes to integer. no need to clean the high bit
// only to shift right because of opposite alignment
IntegerType const& targetIntegerType = dynamic_cast<IntegerType const&>(_targetType);
- m_context << (u256(1) << (256 - typeOnStack.numBytes() * 8)) << Instruction::SWAP1 << Instruction::DIV;
+ rightShiftNumberOnStack(256 - typeOnStack.numBytes() * 8, false);
if (targetIntegerType.numBits() < typeOnStack.numBytes() * 8)
convertType(IntegerType(typeOnStack.numBytes() * 8), _targetType, _cleanupNeeded);
}
@@ -476,7 +480,7 @@ void CompilerUtils::convertType(
if (auto typeOnStack = dynamic_cast<IntegerType const*>(&_typeOnStack))
if (targetBytesType.numBytes() * 8 > typeOnStack->numBits())
cleanHigherOrderBits(*typeOnStack);
- m_context << (u256(1) << (256 - targetBytesType.numBytes() * 8)) << Instruction::MUL;
+ leftShiftNumberOnStack(256 - targetBytesType.numBytes() * 8);
}
else if (targetTypeCategory == Type::Category::Enum)
{
@@ -986,10 +990,10 @@ unsigned CompilerUtils::loadFromMemoryHelper(Type const& _type, bool _fromCallda
{
bool leftAligned = _type.category() == Type::Category::FixedBytes;
// add leading or trailing zeros by dividing/multiplying depending on alignment
- u256 shiftFactor = u256(1) << ((32 - numBytes) * 8);
- m_context << shiftFactor << Instruction::SWAP1 << Instruction::DIV;
+ int shiftFactor = (32 - numBytes) * 8;
+ rightShiftNumberOnStack(shiftFactor, false);
if (leftAligned)
- m_context << shiftFactor << Instruction::MUL;
+ leftShiftNumberOnStack(shiftFactor);
}
if (_fromCalldata)
convertType(_type, _type, true, false, true);
@@ -1007,6 +1011,18 @@ void CompilerUtils::cleanHigherOrderBits(IntegerType const& _typeOnStack)
m_context << ((u256(1) << _typeOnStack.numBits()) - 1) << Instruction::AND;
}
+void CompilerUtils::leftShiftNumberOnStack(unsigned _bits)
+{
+ solAssert(_bits < 256, "");
+ m_context << (u256(1) << _bits) << Instruction::MUL;
+}
+
+void CompilerUtils::rightShiftNumberOnStack(unsigned _bits, bool _isSigned)
+{
+ solAssert(_bits < 256, "");
+ m_context << (u256(1) << _bits) << Instruction::SWAP1 << (_isSigned ? Instruction::SDIV : Instruction::DIV);
+}
+
unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords)
{
unsigned numBytes = _type.calldataEncodedSize(_padToWords);
@@ -1019,7 +1035,7 @@ unsigned CompilerUtils::prepareMemoryStore(Type const& _type, bool _padToWords)
convertType(_type, _type, true);
if (numBytes != 32 && !leftAligned && !_padToWords)
// shift the value accordingly before storing
- m_context << (u256(1) << ((32 - numBytes) * 8)) << Instruction::MUL;
+ leftShiftNumberOnStack((32 - numBytes) * 8);
}
return numBytes;
}
diff --git a/libsolidity/codegen/CompilerUtils.h b/libsolidity/codegen/CompilerUtils.h
index 0ee053a9..fb169463 100644
--- a/libsolidity/codegen/CompilerUtils.h
+++ b/libsolidity/codegen/CompilerUtils.h
@@ -176,6 +176,12 @@ public:
static unsigned sizeOnStack(std::vector<T> const& _variables);
static unsigned sizeOnStack(std::vector<std::shared_ptr<Type const>> const& _variableTypes);
+ /// Helper function to shift top value on the stack to the left.
+ void leftShiftNumberOnStack(unsigned _bits);
+
+ /// Helper function to shift top value on the stack to the right.
+ void rightShiftNumberOnStack(unsigned _bits, bool _isSigned = false);
+
/// Appends code that computes tha Keccak-256 hash of the topmost stack element of 32 byte type.
void computeHashStatic();
diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp
index 9d4024c9..82518e8c 100644
--- a/libsolidity/codegen/ExpressionCompiler.cpp
+++ b/libsolidity/codegen/ExpressionCompiler.cpp
@@ -526,7 +526,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
if (m_context.runtimeContext())
// We have a runtime context, so we need the creation part.
- m_context << (u256(1) << 32) << Instruction::SWAP1 << Instruction::DIV;
+ utils().rightShiftNumberOnStack(32, false);
else
// Extract the runtime part.
m_context << ((u256(1) << 32) - 1) << Instruction::AND;
@@ -1269,7 +1269,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
m_context.appendConditionalInvalid();
m_context << Instruction::BYTE;
- m_context << (u256(1) << (256 - 8)) << Instruction::MUL;
+ utils().leftShiftNumberOnStack(256 - 8);
}
else if (baseType.category() == Type::Category::TypeType)
{
diff --git a/libsolidity/codegen/LValue.cpp b/libsolidity/codegen/LValue.cpp
index a74a3d74..e19cf41e 100644
--- a/libsolidity/codegen/LValue.cpp
+++ b/libsolidity/codegen/LValue.cpp
@@ -186,7 +186,7 @@ void StorageItem::retrieveValue(SourceLocation const&, bool _remove) const
solUnimplemented("Not yet implemented - FixedPointType.");
if (m_dataType->category() == Type::Category::FixedBytes)
{
- m_context << (u256(0x1) << (256 - 8 * m_dataType->storageBytes())) << Instruction::MUL;
+ CompilerUtils(m_context).leftShiftNumberOnStack(256 - 8 * m_dataType->storageBytes());
cleaned = true;
}
else if (
@@ -267,9 +267,7 @@ void StorageItem::storeValue(Type const& _sourceType, SourceLocation const& _loc
else if (m_dataType->category() == Type::Category::FixedBytes)
{
solAssert(_sourceType.category() == Type::Category::FixedBytes, "source not fixed bytes");
- m_context
- << (u256(0x1) << (256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes()))
- << Instruction::SWAP1 << Instruction::DIV;
+ CompilerUtils(m_context).rightShiftNumberOnStack(256 - 8 * dynamic_cast<FixedBytesType const&>(*m_dataType).numBytes(), false);
}
else
{
diff --git a/libsolidity/inlineasm/AsmCodeGen.cpp b/libsolidity/inlineasm/AsmCodeGen.cpp
index 2bbd1b70..74743737 100644
--- a/libsolidity/inlineasm/AsmCodeGen.cpp
+++ b/libsolidity/inlineasm/AsmCodeGen.cpp
@@ -137,7 +137,6 @@ private:
eth::Assembly& m_assembly;
};
-
void assembly::CodeGenerator::assemble(
Block const& _parsedData,
AsmAnalysisInfo& _analysisInfo,
@@ -146,5 +145,5 @@ void assembly::CodeGenerator::assemble(
)
{
EthAssemblyAdapter assemblyAdapter(_assembly);
- julia::CodeTransform(assemblyAdapter, _analysisInfo, false, _identifierAccess)(_parsedData);
+ julia::CodeTransform(assemblyAdapter, _analysisInfo, false, false, _identifierAccess)(_parsedData);
}
diff --git a/libsolidity/interface/AssemblyStack.cpp b/libsolidity/interface/AssemblyStack.cpp
index 2d85895e..23524bb3 100644
--- a/libsolidity/interface/AssemblyStack.cpp
+++ b/libsolidity/interface/AssemblyStack.cpp
@@ -72,7 +72,7 @@ bool AssemblyStack::analyze(assembly::Block const& _block, Scanner const* _scann
bool AssemblyStack::analyzeParsed()
{
m_analysisInfo = make_shared<assembly::AsmAnalysisInfo>();
- assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter);
+ assembly::AsmAnalyzer analyzer(*m_analysisInfo, m_errorReporter, m_language == Language::JULIA);
m_analysisSuccessful = analyzer.analyze(*m_parserResult);
return m_analysisSuccessful;
}
@@ -100,7 +100,7 @@ MachineAssemblyObject AssemblyStack::assemble(Machine _machine) const
{
MachineAssemblyObject object;
julia::EVMAssembly assembly(true);
- julia::CodeTransform(assembly, *m_analysisInfo, true)(*m_parserResult);
+ julia::CodeTransform(assembly, *m_analysisInfo, m_language == Language::JULIA, true)(*m_parserResult);
object.bytecode = make_shared<eth::LinkerObject>(assembly.finalize());
/// TOOD: fill out text representation
return object;