From 499cb0526f37a3939de76dc1e62a12a2419b19f0 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 25 May 2020 19:30:17 +0200 Subject: [PATCH] Calldata variables. --- libsolidity/ast/AST.cpp | 23 ++++++++++++----------- libsolidity/codegen/CompilerUtils.cpp | 9 +++++++++ libsolidity/codegen/YulUtilFunctions.cpp | 22 +++++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index e553e45bd..3d98ff169 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -338,8 +338,14 @@ TypePointer FunctionDefinition::type() const TypePointer FunctionDefinition::typeViaContractName() const { if (annotation().contract->isLibrary()) - return FunctionType(*this).asCallableFunction(true); - return TypeProvider::function(*this, FunctionType::Kind::Declaration); + { + if (isPublic()) + return FunctionType(*this).asCallableFunction(true); + else + return TypeProvider::function(*this, FunctionType::Kind::Internal); + } + else + return TypeProvider::function(*this, FunctionType::Kind::Declaration); } string FunctionDefinition::externalSignature() const @@ -616,18 +622,14 @@ set VariableDeclaration::allowedDataLocations() c if (!hasReferenceOrMappingType() || isStateVariable() || isEventParameter()) return set{ Location::Unspecified }; - else if (isExternalCallableParameter()) - { - set locations{ Location::CallData }; - if (isLibraryFunctionParameter()) - locations.insert(Location::Storage); - return locations; - } else if (isCallableOrCatchParameter()) { set locations{ Location::Memory }; if (isInternalCallableParameter() || isLibraryFunctionParameter() || isTryCatchParameter()) locations.insert(Location::Storage); + if (!isTryCatchParameter()) + locations.insert(Location::CallData); + return locations; } else if (isLocalVariable()) @@ -642,8 +644,7 @@ set VariableDeclaration::allowedDataLocations() c case Type::Category::Mapping: return set{ Location::Storage }; default: - // TODO: add Location::Calldata once implemented for local variables. - return set{ Location::Memory, Location::Storage }; + return set{ Location::Memory, Location::Storage, Location::CallData }; } }; return dataLocations(typeName()->annotation().type, dataLocations); diff --git a/libsolidity/codegen/CompilerUtils.cpp b/libsolidity/codegen/CompilerUtils.cpp index 25c91f0a3..225a9fe8e 100644 --- a/libsolidity/codegen/CompilerUtils.cpp +++ b/libsolidity/codegen/CompilerUtils.cpp @@ -1218,6 +1218,15 @@ void CompilerUtils::pushZeroValue(Type const& _type) m_context << u256(0); return; } + if (referenceType->location() == DataLocation::CallData) + { + solAssert(referenceType->sizeOnStack() == 1 || referenceType->sizeOnStack() == 2, ""); + m_context << Instruction::CALLDATASIZE; + if (referenceType->sizeOnStack() == 2) + m_context << 0; + return; + } + solAssert(referenceType->location() == DataLocation::Memory, ""); if (auto arrayType = dynamic_cast(&_type)) if (arrayType->isDynamicallySized()) diff --git a/libsolidity/codegen/YulUtilFunctions.cpp b/libsolidity/codegen/YulUtilFunctions.cpp index 64639efb1..05912962a 100644 --- a/libsolidity/codegen/YulUtilFunctions.cpp +++ b/libsolidity/codegen/YulUtilFunctions.cpp @@ -2238,6 +2238,27 @@ string YulUtilFunctions::zeroValueFunction(Type const& _type, bool _splitFunctio ("functionName", functionName) .render(); + if (_type.dataStoredIn(DataLocation::CallData)) + { + solAssert( + _type.category() == Type::Category::Struct || + _type.category() == Type::Category::Array, + ""); + Whiskers templ(R"( + function () -> offset, length { + offset := calldatasize() + length := 0 + } + )"); + templ("functionName", functionName); + templ("hasLength", + _type.category() == Type::Category::Array && + dynamic_cast(_type).isDynamicallySized() + ); + + return templ.render(); + } + Whiskers templ(R"( function () -> ret { ret := @@ -2622,4 +2643,3 @@ string YulUtilFunctions::copyConstructorArgumentsToMemoryFunction( .render(); }); } -