libsolidity: Introducing TypeProvider API, for clear type system ownership.

This commit is contained in:
Christian Parpart
2019-04-16 18:26:45 +02:00
committed by chriseth
parent 862d798047
commit bf43eebea9
38 changed files with 1489 additions and 837 deletions
+6 -6
View File
@@ -311,7 +311,7 @@ string ABIFunctions::abiEncodingFunction(
case DataLocation::CallData:
if (
fromArray.isByteArray() ||
*fromArray.baseType() == IntegerType::uint256() ||
*fromArray.baseType() == *TypeProvider::integerType() ||
*fromArray.baseType() == FixedBytesType(32)
)
return abiEncodingFunctionCalldataArrayWithoutCleanup(fromArray, *toArray, _options);
@@ -369,7 +369,7 @@ string ABIFunctions::abiEncodingFunction(
// possible for library calls where we just forward the storage reference
solAssert(_options.encodeAsLibraryTypes, "");
solAssert(_options.padded && !_options.dynamicInplace, "Non-padded / inplace encoding for library call requested.");
solAssert(to == IntegerType::uint256(), "");
solAssert(to == *TypeProvider::integerType(), "");
templ("cleanupConvert", "value");
}
else
@@ -445,7 +445,7 @@ string ABIFunctions::abiEncodingFunctionCalldataArrayWithoutCleanup(
solAssert(fromArrayType.location() == DataLocation::CallData, "");
solAssert(
fromArrayType.isByteArray() ||
*fromArrayType.baseType() == IntegerType::uint256() ||
*fromArrayType.baseType() == *TypeProvider::integerType() ||
*fromArrayType.baseType() == FixedBytesType(32),
"");
solAssert(fromArrayType.calldataStride() == toArrayType.memoryStride(), "");
@@ -1077,7 +1077,7 @@ string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bo
TypePointer decodingType = _type.decodingType();
solAssert(decodingType, "");
if (auto arrayType = dynamic_cast<ArrayType const*>(decodingType.get()))
if (auto arrayType = dynamic_cast<ArrayType const*>(decodingType))
{
if (arrayType->dataStoredIn(DataLocation::CallData))
{
@@ -1089,7 +1089,7 @@ string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bo
else
return abiDecodingFunctionArray(*arrayType, _fromMemory);
}
else if (auto const* structType = dynamic_cast<StructType const*>(decodingType.get()))
else if (auto const* structType = dynamic_cast<StructType const*>(decodingType))
{
if (structType->dataStoredIn(DataLocation::CallData))
{
@@ -1099,7 +1099,7 @@ string ABIFunctions::abiDecodingFunction(Type const& _type, bool _fromMemory, bo
else
return abiDecodingFunctionStruct(*structType, _fromMemory);
}
else if (auto const* functionType = dynamic_cast<FunctionType const*>(decodingType.get()))
else if (auto const* functionType = dynamic_cast<FunctionType const*>(decodingType))
return abiDecodingFunctionFunctionType(*functionType, _fromMemory, _forUseOnStack);
else
return abiDecodingFunctionValueType(_type, _fromMemory);
+1 -1
View File
@@ -41,7 +41,7 @@ class Type;
class ArrayType;
class StructType;
class FunctionType;
using TypePointer = std::shared_ptr<Type const>;
using TypePointer = Type const*;
using TypePointers = std::vector<TypePointer>;
/**
+13 -12
View File
@@ -23,6 +23,7 @@
#include <libsolidity/codegen/ArrayUtils.h>
#include <libsolidity/ast/Types.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/codegen/LValue.h>
@@ -44,7 +45,7 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
// stack layout: [source_ref] [source length] target_ref (top)
solAssert(_targetType.location() == DataLocation::Storage, "");
TypePointer uint256 = make_shared<IntegerType>(256);
TypePointer uint256 = TypeProvider::integerType(256);
TypePointer targetBaseType = _targetType.isByteArray() ? uint256 : _targetType.baseType();
TypePointer sourceBaseType = _sourceType.isByteArray() ? uint256 : _sourceType.baseType();
@@ -74,8 +75,8 @@ void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType cons
}
// stack: target_ref source_ref source_length
TypePointer targetType = _targetType.shared_from_this();
TypePointer sourceType = _sourceType.shared_from_this();
TypePointer targetType = &_targetType;
TypePointer sourceType = &_sourceType;
m_context.callLowLevelFunction(
"$copyArrayToStorage_" + sourceType->identifier() + "_to_" + targetType->identifier(),
3,
@@ -336,7 +337,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
m_context << Instruction::DUP3 << Instruction::DUP5;
accessIndex(_sourceType, false);
MemoryItem(m_context, *_sourceType.baseType(), true).retrieveValue(SourceLocation(), true);
if (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType().get()))
if (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType()))
copyArrayToMemory(*baseArray, _padToWordBoundaries);
else
utils.storeInMemoryDynamic(*_sourceType.baseType());
@@ -493,7 +494,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
else
m_context << Instruction::DUP2 << u256(0);
StorageItem(m_context, *_sourceType.baseType()).retrieveValue(SourceLocation(), true);
if (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType().get()))
if (auto baseArray = dynamic_cast<ArrayType const*>(_sourceType.baseType()))
copyArrayToMemory(*baseArray, _padToWordBoundaries);
else
utils.storeInMemoryDynamic(*_sourceType.baseType());
@@ -530,7 +531,7 @@ void ArrayUtils::copyArrayToMemory(ArrayType const& _sourceType, bool _padToWord
void ArrayUtils::clearArray(ArrayType const& _typeIn) const
{
TypePointer type = _typeIn.shared_from_this();
TypePointer type = &_typeIn;
m_context.callLowLevelFunction(
"$clearArray_" + _typeIn.identifier(),
2,
@@ -584,7 +585,7 @@ void ArrayUtils::clearArray(ArrayType const& _typeIn) const
ArrayUtils(_context).convertLengthToSize(_type);
_context << Instruction::ADD << Instruction::SWAP1;
if (_type.baseType()->storageBytes() < 32)
ArrayUtils(_context).clearStorageLoop(make_shared<IntegerType>(256));
ArrayUtils(_context).clearStorageLoop(TypeProvider::integerType(256));
else
ArrayUtils(_context).clearStorageLoop(_type.baseType());
_context << Instruction::POP;
@@ -625,7 +626,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const
<< Instruction::SWAP1;
// stack: data_pos_end data_pos
if (_type.storageStride() < 32)
clearStorageLoop(make_shared<IntegerType>(256));
clearStorageLoop(TypeProvider::integerType(256));
else
clearStorageLoop(_type.baseType());
// cleanup
@@ -635,7 +636,7 @@ void ArrayUtils::clearDynamicArray(ArrayType const& _type) const
void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
{
TypePointer type = _typeIn.shared_from_this();
TypePointer type = &_typeIn;
m_context.callLowLevelFunction(
"$resizeDynamicArray_" + _typeIn.identifier(),
2,
@@ -732,7 +733,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
ArrayUtils(_context).convertLengthToSize(_type);
_context << Instruction::DUP2 << Instruction::ADD << Instruction::SWAP1;
// stack: ref new_length current_length first_word data_location_end data_location
ArrayUtils(_context).clearStorageLoop(make_shared<IntegerType>(256));
ArrayUtils(_context).clearStorageLoop(TypeProvider::integerType(256));
_context << Instruction::POP;
// stack: ref new_length current_length first_word
solAssert(_context.stackHeight() - stackHeightStart == 4 - 2, "3");
@@ -771,7 +772,7 @@ void ArrayUtils::resizeDynamicArray(ArrayType const& _typeIn) const
_context << Instruction::SWAP2 << Instruction::ADD;
// stack: ref new_length delete_end delete_start
if (_type.storageStride() < 32)
ArrayUtils(_context).clearStorageLoop(make_shared<IntegerType>(256));
ArrayUtils(_context).clearStorageLoop(TypeProvider::integerType(256));
else
ArrayUtils(_context).clearStorageLoop(_type.baseType());
@@ -911,7 +912,7 @@ void ArrayUtils::popStorageArrayElement(ArrayType const& _type) const
}
}
void ArrayUtils::clearStorageLoop(TypePointer const& _type) const
void ArrayUtils::clearStorageLoop(TypePointer _type) const
{
m_context.callLowLevelFunction(
"$clearStorageLoop_" + _type->identifier(),
+2 -2
View File
@@ -32,7 +32,7 @@ namespace solidity
class CompilerContext;
class Type;
class ArrayType;
using TypePointer = std::shared_ptr<Type const>;
using TypePointer = Type const*;
/**
* Class that provides code generation for handling arrays.
@@ -81,7 +81,7 @@ public:
/// Appends a loop that clears a sequence of storage slots of the given type (excluding end).
/// Stack pre: end_ref start_ref
/// Stack post: end_ref
void clearStorageLoop(TypePointer const& _type) const;
void clearStorageLoop(TypePointer _type) const;
/// Converts length to size (number of storage slots or calldata/memory bytes).
/// if @a _pad then add padding to multiples of 32 bytes for calldata/memory.
/// Stack pre: length
+23 -23
View File
@@ -23,6 +23,7 @@
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolidity/codegen/ABIFunctions.h>
#include <libsolidity/codegen/ArrayUtils.h>
#include <libsolidity/codegen/LValue.h>
@@ -83,13 +84,13 @@ void CompilerUtils::toSizeAfterFreeMemoryPointer()
void CompilerUtils::revertWithStringData(Type const& _argumentType)
{
solAssert(_argumentType.isImplicitlyConvertibleTo(*Type::fromElementaryTypeName("string memory")), "");
solAssert(_argumentType.isImplicitlyConvertibleTo(*TypeProvider::fromElementaryTypeName("string memory")), "");
fetchFreeMemoryPointer();
m_context << (u256(FixedHash<4>::Arith(FixedHash<4>(dev::keccak256("Error(string)")))) << (256 - 32));
m_context << Instruction::DUP2 << Instruction::MSTORE;
m_context << u256(4) << Instruction::ADD;
// Stack: <string data> <mem pos of encoding start>
abiEncode({_argumentType.shared_from_this()}, {make_shared<ArrayType>(DataLocation::Memory, true)});
abiEncode({&_argumentType}, {TypeProvider::arrayType(DataLocation::Memory, true)});
toSizeAfterFreeMemoryPointer();
m_context << Instruction::REVERT;
}
@@ -185,7 +186,7 @@ void CompilerUtils::loadFromMemoryDynamic(
void CompilerUtils::storeInMemory(unsigned _offset)
{
unsigned numBytes = prepareMemoryStore(IntegerType::uint256(), true);
unsigned numBytes = prepareMemoryStore(*TypeProvider::integerType(), true);
if (numBytes > 0)
m_context << u256(_offset) << Instruction::MSTORE;
}
@@ -199,7 +200,7 @@ void CompilerUtils::storeInMemoryDynamic(Type const& _type, bool _padToWordBound
ref->location() == DataLocation::Memory,
"Only in-memory reference type can be stored."
);
storeInMemoryDynamic(IntegerType::uint256(), _padToWordBoundaries);
storeInMemoryDynamic(*TypeProvider::integerType(), _padToWordBoundaries);
}
else if (auto str = dynamic_cast<StringLiteralType const*>(&_type))
{
@@ -311,11 +312,11 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
else
{
// first load from calldata and potentially convert to memory if arrayType is memory
TypePointer calldataType = arrayType.copyForLocation(DataLocation::CallData, false);
TypePointer calldataType = TypeProvider::withLocation(&arrayType, DataLocation::CallData, false);
if (calldataType->isDynamicallySized())
{
// put on stack: data_pointer length
loadFromMemoryDynamic(IntegerType::uint256(), !_fromMemory);
loadFromMemoryDynamic(*TypeProvider::integerType(), !_fromMemory);
m_context << Instruction::SWAP1;
// stack: input_end base_offset next_pointer data_offset
m_context.appendInlineAssembly("{ if gt(data_offset, 0x100000000) { revert(0, 0) } }", {"data_offset"});
@@ -326,7 +327,7 @@ void CompilerUtils::abiDecode(TypePointers const& _typeParameters, bool _fromMem
{"input_end", "base_offset", "next_ptr", "array_head_ptr"}
);
// retrieve length
loadFromMemoryDynamic(IntegerType::uint256(), !_fromMemory, true);
loadFromMemoryDynamic(*TypeProvider::integerType(), !_fromMemory, true);
// stack: input_end base_offset next_pointer array_length data_pointer
m_context << Instruction::SWAP2;
// stack: input_end base_offset data_pointer array_length next_pointer
@@ -454,7 +455,7 @@ void CompilerUtils::encodeToMemory(
type = _givenTypes[i]; // delay conversion
else
convertType(*_givenTypes[i], *targetType, true);
if (auto arrayType = dynamic_cast<ArrayType const*>(type.get()))
if (auto arrayType = dynamic_cast<ArrayType const*>(type))
ArrayUtils(m_context).copyArrayToMemory(*arrayType, _padToWordBoundaries);
else
storeInMemoryDynamic(*type, _padToWordBoundaries);
@@ -482,7 +483,7 @@ void CompilerUtils::encodeToMemory(
{
auto const& strType = dynamic_cast<StringLiteralType const&>(*_givenTypes[i]);
m_context << u256(strType.value().size());
storeInMemoryDynamic(IntegerType::uint256(), true);
storeInMemoryDynamic(*TypeProvider::integerType(), true);
// stack: ... <end_of_mem'>
storeInMemoryDynamic(strType, _padToWordBoundaries);
}
@@ -497,7 +498,7 @@ void CompilerUtils::encodeToMemory(
m_context << dupInstruction(1 + arrayType.sizeOnStack());
ArrayUtils(m_context).retrieveLength(arrayType, 1);
// stack: ... <end_of_mem> <value...> <end_of_mem'> <length>
storeInMemoryDynamic(IntegerType::uint256(), true);
storeInMemoryDynamic(*TypeProvider::integerType(), true);
// stack: ... <end_of_mem> <value...> <end_of_mem''>
// copy the new memory pointer
m_context << swapInstruction(arrayType.sizeOnStack() + 1) << Instruction::POP;
@@ -868,7 +869,7 @@ void CompilerUtils::convertType(
allocateMemory(storageSize);
// stack: mempos
m_context << Instruction::DUP1 << u256(data.size());
storeInMemoryDynamic(IntegerType::uint256());
storeInMemoryDynamic(*TypeProvider::integerType());
// stack: mempos datapos
storeStringData(data);
}
@@ -917,7 +918,7 @@ void CompilerUtils::convertType(
if (targetType.isDynamicallySized())
{
m_context << Instruction::DUP2;
storeInMemoryDynamic(IntegerType::uint256());
storeInMemoryDynamic(*TypeProvider::integerType());
}
// stack: <mem start> <source ref> (variably sized) <length> <mem data pos>
if (targetType.baseType()->isValueType())
@@ -988,10 +989,9 @@ void CompilerUtils::convertType(
{
case DataLocation::Storage:
{
auto conversionImpl = [
typeOnStack = dynamic_pointer_cast<StructType const>(_typeOnStack.shared_from_this()),
targetType = dynamic_pointer_cast<StructType const>(targetType.shared_from_this())
](CompilerContext& _context) {
auto conversionImpl =
[typeOnStack = &typeOnStack, targetType = &targetType](CompilerContext& _context)
{
CompilerUtils utils(_context);
// stack: <source ref>
utils.allocateMemory(typeOnStack->memorySize());
@@ -1029,7 +1029,7 @@ void CompilerUtils::convertType(
m_context << Instruction::DUP1;
m_context << Instruction::CALLDATASIZE;
m_context << Instruction::SUB;
abiDecode({targetType.shared_from_this()}, false);
abiDecode({&targetType}, false);
break;
}
case DataLocation::Memory:
@@ -1162,7 +1162,7 @@ void CompilerUtils::pushZeroValue(Type const& _type)
return;
}
TypePointer type = _type.shared_from_this();
TypePointer type = &_type;
m_context.callLowLevelFunction(
"$pushZeroValue_" + referenceType->identifier(),
0,
@@ -1172,13 +1172,13 @@ void CompilerUtils::pushZeroValue(Type const& _type)
utils.allocateMemory(max(32u, type->calldataEncodedSize()));
_context << Instruction::DUP1;
if (auto structType = dynamic_cast<StructType const*>(type.get()))
if (auto structType = dynamic_cast<StructType const*>(type))
for (auto const& member: structType->members(nullptr))
{
utils.pushZeroValue(*member.type);
utils.storeInMemoryDynamic(*member.type);
}
else if (auto arrayType = dynamic_cast<ArrayType const*>(type.get()))
else if (auto arrayType = dynamic_cast<ArrayType const*>(type))
{
solAssert(!arrayType->isDynamicallySized(), "");
if (arrayType->length() > 0)
@@ -1275,10 +1275,10 @@ void CompilerUtils::popAndJump(unsigned _toHeight, eth::AssemblyItem const& _jum
m_context.adjustStackOffset(amount);
}
unsigned CompilerUtils::sizeOnStack(vector<shared_ptr<Type const>> const& _variableTypes)
unsigned CompilerUtils::sizeOnStack(vector<Type const*> const& _variableTypes)
{
unsigned size = 0;
for (shared_ptr<Type const> const& type: _variableTypes)
for (Type const* const& type: _variableTypes)
size += type->sizeOnStack();
return size;
}
@@ -1321,7 +1321,7 @@ void CompilerUtils::storeStringData(bytesConstRef _data)
for (unsigned i = 0; i < _data.size(); i += 32)
{
m_context << h256::Arith(h256(_data.cropped(i), h256::AlignLeft));
storeInMemoryDynamic(IntegerType::uint256());
storeInMemoryDynamic(*TypeProvider::integerType());
}
m_context << Instruction::POP;
}
+4 -2
View File
@@ -23,6 +23,8 @@
#pragma once
#include <libsolidity/ast/ASTForward.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/CompilerContext.h>
namespace dev {
@@ -80,7 +82,7 @@ public:
/// @returns the number of bytes consumed in memory.
unsigned loadFromMemory(
unsigned _offset,
Type const& _type = IntegerType::uint256(),
Type const& _type = *TypeProvider::integerType(),
bool _fromCalldata = false,
bool _padToWords = false
);
@@ -264,7 +266,7 @@ public:
template <class T>
static unsigned sizeOnStack(std::vector<T> const& _variables);
static unsigned sizeOnStack(std::vector<std::shared_ptr<Type const>> const& _variableTypes);
static unsigned sizeOnStack(std::vector<Type const*> const& _variableTypes);
/// Helper function to shift top value on the stack to the left.
/// Stack pre: <value> <shift_by_bits>
+3 -2
View File
@@ -21,6 +21,7 @@
*/
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/codegen/ContractCompiler.h>
#include <libsolidity/codegen/ExpressionCompiler.h>
@@ -871,7 +872,7 @@ bool ContractCompiler::visit(Return const& _return)
TypePointer expectedType;
if (expression->annotation().type->category() == Type::Category::Tuple || types.size() != 1)
expectedType = make_shared<TupleType>(types);
expectedType = TypeProvider::tupleType(move(types));
else
expectedType = types.front();
compileExpression(*expression, expectedType);
@@ -915,7 +916,7 @@ bool ContractCompiler::visit(VariableDeclarationStatement const& _variableDeclar
CompilerUtils utils(m_context);
compileExpression(*expression);
TypePointers valueTypes;
if (auto tupleType = dynamic_cast<TupleType const*>(expression->annotation().type.get()))
if (auto tupleType = dynamic_cast<TupleType const*>(expression->annotation().type))
valueTypes = tupleType->components();
else
valueTypes = TypePointers{expression->annotation().type};
+35 -34
View File
@@ -23,6 +23,7 @@
#include <libsolidity/codegen/ExpressionCompiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/ast/TypeProvider.h>
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/codegen/LValue.h>
@@ -102,7 +103,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
for (size_t i = 0; i < paramTypes.size(); ++i)
{
if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get()))
if (auto mappingType = dynamic_cast<MappingType const*>(returnType))
{
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
@@ -152,7 +153,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
m_context << u256(0);
returnType = mappingType->valueType();
}
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get()))
else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType))
{
// pop offset
m_context << Instruction::POP;
@@ -176,7 +177,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
unsigned retSizeOnStack = 0;
auto returnTypes = accessorType.returnParameterTypes();
solAssert(returnTypes.size() >= 1, "");
if (StructType const* structType = dynamic_cast<StructType const*>(returnType.get()))
if (StructType const* structType = dynamic_cast<StructType const*>(returnType))
{
// remove offset
m_context << Instruction::POP;
@@ -186,7 +187,7 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
{
if (returnTypes[i]->category() == Type::Category::Mapping)
continue;
if (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i].get()))
if (auto arrayType = dynamic_cast<ArrayType const*>(returnTypes[i]))
if (!arrayType->isByteArray())
continue;
pair<u256, unsigned> const& offsets = structType->storageOffsetsOfMember(names[i]);
@@ -496,7 +497,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
functionType = structType.constructorType();
}
else
functionType = dynamic_pointer_cast<FunctionType const>(_functionCall.expression().annotation().type);
functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);
TypePointers parameterTypes = functionType->parameterTypes();
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.arguments();
@@ -647,7 +648,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
_functionCall.expression().accept(*this);
arguments.front()->accept(*this);
utils().convertType(*arguments.front()->annotation().type, IntegerType::uint256(), true);
utils().convertType(*arguments.front()->annotation().type, *TypeProvider::integerType(), true);
// Note that function is not the original function, but the ".gas" function.
// Its values of gasSet and valueSet is equal to the original function's though.
unsigned stackDepth = (function.gasSet() ? 1 : 0) + (function.valueSet() ? 1 : 0);
@@ -731,9 +732,9 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments.front()->accept(*this);
// Optimization: If type is bytes or string, then do not encode,
// but directly compute keccak256 on memory.
if (*argType == ArrayType::bytesMemory() || *argType == ArrayType::stringMemory())
if (*argType == *TypeProvider::bytesMemoryType() || *argType == *TypeProvider::stringMemoryType())
{
ArrayUtils(m_context).retrieveLength(ArrayType::bytesMemory());
ArrayUtils(m_context).retrieveLength(*TypeProvider::bytesMemoryType());
m_context << Instruction::SWAP1 << u256(0x20) << Instruction::ADD;
}
else
@@ -780,7 +781,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
{
++numIndexed;
arguments[arg - 1]->accept(*this);
if (auto const& referenceType = dynamic_pointer_cast<ReferenceType const>(paramTypes[arg - 1]))
if (auto const& referenceType = dynamic_cast<ReferenceType const*>(paramTypes[arg - 1]))
{
utils().fetchFreeMemoryPointer();
utils().packedEncode(
@@ -835,13 +836,13 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
case FunctionType::Kind::MulMod:
{
arguments[2]->accept(*this);
utils().convertType(*arguments[2]->annotation().type, IntegerType::uint256());
utils().convertType(*arguments[2]->annotation().type, *TypeProvider::integerType());
m_context << Instruction::DUP1 << Instruction::ISZERO;
m_context.appendConditionalInvalid();
for (unsigned i = 1; i < 3; i ++)
{
arguments[2 - i]->accept(*this);
utils().convertType(*arguments[2 - i]->annotation().type, IntegerType::uint256());
utils().convertType(*arguments[2 - i]->annotation().type, *TypeProvider::integerType());
}
if (function.kind() == FunctionType::Kind::AddMod)
m_context << Instruction::ADDMOD;
@@ -872,10 +873,10 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
solAssert(function.parameterTypes().size() == 1, "");
solAssert(!!function.parameterTypes()[0], "");
TypePointer paramType = function.parameterTypes()[0];
shared_ptr<ArrayType> arrayType =
ArrayType const* arrayType =
function.kind() == FunctionType::Kind::ArrayPush ?
make_shared<ArrayType>(DataLocation::Storage, paramType) :
make_shared<ArrayType>(DataLocation::Storage);
TypeProvider::arrayType(DataLocation::Storage, paramType) :
TypeProvider::arrayType(DataLocation::Storage);
// stack: ArrayReference
arguments[0]->accept(*this);
@@ -927,7 +928,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
// Fetch requested length.
arguments[0]->accept(*this);
utils().convertType(*arguments[0]->annotation().type, IntegerType::uint256());
utils().convertType(*arguments[0]->annotation().type, *TypeProvider::integerType());
// Stack: requested_length
utils().fetchFreeMemoryPointer();
@@ -1057,11 +1058,11 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
if (function.kind() == FunctionType::Kind::ABIEncodeWithSignature)
{
// hash the signature
if (auto const* stringType = dynamic_cast<StringLiteralType const*>(selectorType.get()))
if (auto const* stringType = dynamic_cast<StringLiteralType const*>(selectorType))
{
FixedHash<4> hash(dev::keccak256(stringType->value()));
m_context << (u256(FixedHash<4>::Arith(hash)) << (256 - 32));
dataOnStack = make_shared<FixedBytesType>(4);
dataOnStack = TypeProvider::fixedBytesType(4);
}
else
{
@@ -1072,7 +1073,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
m_context << Instruction::KECCAK256;
// stack: <memory pointer> <hash>
dataOnStack = make_shared<FixedBytesType>(32);
dataOnStack = TypeProvider::fixedBytesType(32);
}
}
else
@@ -1103,7 +1104,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
arguments.front()->accept(*this);
TypePointer firstArgType = arguments.front()->annotation().type;
TypePointers targetTypes;
if (TupleType const* targetTupleType = dynamic_cast<TupleType const*>(_functionCall.annotation().type.get()))
if (TupleType const* targetTupleType = dynamic_cast<TupleType const*>(_functionCall.annotation().type))
targetTypes = targetTupleType->components();
else
targetTypes = TypePointers{_functionCall.annotation().type};
@@ -1114,7 +1115,7 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
utils().abiDecode(targetTypes, false);
else
{
utils().convertType(*firstArgType, ArrayType::bytesMemory());
utils().convertType(*firstArgType, *TypeProvider::bytesMemoryType());
m_context << Instruction::DUP1 << u256(32) << Instruction::ADD;
m_context << Instruction::SWAP1 << Instruction::MLOAD;
// stack now: <mem_pos> <length>
@@ -1145,7 +1146,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
CompilerContext::LocationSetter locationSetter(m_context, _memberAccess);
// Check whether the member is a bound function.
ASTString const& member = _memberAccess.memberName();
if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get()))
if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
if (funType->bound())
{
_memberAccess.expression().accept(*this);
@@ -1174,14 +1175,14 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
// Special processing for TypeType because we do not want to visit the library itself
// for internal functions, or enum/struct definitions.
if (TypeType const* type = dynamic_cast<TypeType const*>(_memberAccess.expression().annotation().type.get()))
if (TypeType const* type = dynamic_cast<TypeType const*>(_memberAccess.expression().annotation().type))
{
if (dynamic_cast<ContractType const*>(type->actualType().get()))
if (dynamic_cast<ContractType const*>(type->actualType()))
{
solAssert(_memberAccess.annotation().type, "_memberAccess has no type");
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get()))
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type))
{
switch (funType->kind())
{
@@ -1223,14 +1224,14 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
solAssert(false, "unsupported member function");
}
}
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type.get()))
else if (dynamic_cast<TypeType const*>(_memberAccess.annotation().type))
{
// no-op
}
else
_memberAccess.expression().accept(*this);
}
else if (auto enumType = dynamic_cast<EnumType const*>(type->actualType().get()))
else if (auto enumType = dynamic_cast<EnumType const*>(type->actualType()))
{
_memberAccess.expression().accept(*this);
m_context << enumType->memberValue(_memberAccess.memberName());
@@ -1288,7 +1289,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
identifier = FunctionType(*function).externalIdentifier();
else
solAssert(false, "Contract member is neither variable nor function.");
utils().convertType(type, type.isPayable() ? AddressType::addressPayable() : AddressType::address(), true);
utils().convertType(type, type.isPayable() ? *TypeProvider::payableAddressType() : *TypeProvider::addressType(), true);
m_context << identifier;
}
else
@@ -1306,7 +1307,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
utils().convertType(
*_memberAccess.expression().annotation().type,
AddressType::address(),
*TypeProvider::addressType(),
true
);
m_context << Instruction::BALANCE;
@@ -1323,7 +1324,7 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
else if ((set<string>{"call", "callcode", "delegatecall", "staticcall"}).count(member))
utils().convertType(
*_memberAccess.expression().annotation().type,
AddressType::address(),
*TypeProvider::addressType(),
true
);
else
@@ -1542,7 +1543,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
TypePointers{keyType}
);
m_context << Instruction::SWAP1;
utils().storeInMemoryDynamic(IntegerType::uint256());
utils().storeInMemoryDynamic(*TypeProvider::integerType());
utils().toSizeAfterFreeMemoryPointer();
}
else
@@ -1551,7 +1552,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
appendExpressionCopyToMemory(*keyType, *_indexAccess.indexExpression());
m_context << Instruction::SWAP1;
solAssert(CompilerUtils::freeMemoryPointer >= 0x40, "");
utils().storeInMemoryDynamic(IntegerType::uint256());
utils().storeInMemoryDynamic(*TypeProvider::integerType());
m_context << u256(0);
}
m_context << Instruction::KECCAK256;
@@ -1564,7 +1565,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
solAssert(_indexAccess.indexExpression(), "Index expression expected.");
_indexAccess.indexExpression()->accept(*this);
utils().convertType(*_indexAccess.indexExpression()->annotation().type, IntegerType::uint256(), true);
utils().convertType(*_indexAccess.indexExpression()->annotation().type, *TypeProvider::integerType(), true);
// stack layout: <base_ref> [<length>] <index>
switch (arrayType.location())
{
@@ -1631,7 +1632,7 @@ bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
solAssert(_indexAccess.indexExpression(), "Index expression expected.");
_indexAccess.indexExpression()->accept(*this);
utils().convertType(*_indexAccess.indexExpression()->annotation().type, IntegerType::uint256(), true);
utils().convertType(*_indexAccess.indexExpression()->annotation().type, *TypeProvider::integerType(), true);
// stack layout: <value> <index>
// check out-of-bounds access
m_context << u256(fixedBytesType.numBytes());
@@ -2211,7 +2212,7 @@ void ExpressionCompiler::appendExternalFunctionCall(
needToUpdateFreeMemoryPtr = true;
else
for (auto const& retType: returnTypes)
if (dynamic_cast<ReferenceType const*>(retType.get()))
if (dynamic_cast<ReferenceType const*>(retType))
needToUpdateFreeMemoryPtr = true;
// Stack: return_data_start
+2 -2
View File
@@ -35,7 +35,7 @@ using namespace langutil;
StackVariable::StackVariable(CompilerContext& _compilerContext, VariableDeclaration const& _declaration):
LValue(_compilerContext, _declaration.annotation().type.get()),
LValue(_compilerContext, _declaration.annotation().type),
m_baseStackOffset(m_context.baseStackOffsetOfVariable(_declaration)),
m_size(m_dataType->sizeOnStack())
{
@@ -475,7 +475,7 @@ void StorageByteArrayElement::setToZero(SourceLocation const&, bool _removeRefer
}
StorageArrayLength::StorageArrayLength(CompilerContext& _compilerContext, ArrayType const& _arrayType):
LValue(_compilerContext, _arrayType.memberType("length").get()),
LValue(_compilerContext, _arrayType.memberType("length")),
m_arrayType(_arrayType)
{
solAssert(m_arrayType.isDynamicallySized(), "");
+1 -1
View File
@@ -145,7 +145,7 @@ string YulUtilFunctions::leftAlignFunction(Type const& _type)
templ("body", "aligned := value");
break;
case Type::Category::Contract:
templ("body", "aligned := " + leftAlignFunction(AddressType::address()) + "(value)");
templ("body", "aligned := " + leftAlignFunction(*TypeProvider::addressType()) + "(value)");
break;
case Type::Category::Enum:
{
@@ -82,7 +82,7 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binOp)
{
solUnimplementedAssert(_binOp.getOperator() == Token::Add, "");
solUnimplementedAssert(*_binOp.leftExpression().annotation().type == *_binOp.rightExpression().annotation().type, "");
if (IntegerType const* type = dynamic_cast<IntegerType const*>(_binOp.annotation().commonType.get()))
if (IntegerType const* type = dynamic_cast<IntegerType const*>(_binOp.annotation().commonType))
{
solUnimplementedAssert(!type->isSigned(), "");
m_code <<
@@ -103,7 +103,7 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binOp)
bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall)
{
solUnimplementedAssert(_functionCall.annotation().kind == FunctionCallKind::FunctionCall, "");
FunctionTypePointer functionType = dynamic_pointer_cast<FunctionType const>(_functionCall.expression().annotation().type);
FunctionTypePointer functionType = dynamic_cast<FunctionType const*>(_functionCall.expression().annotation().type);
TypePointers parameterTypes = functionType->parameterTypes();
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.arguments();