Solidity: inline functions

Created on 11 Apr 2016  路  3Comments  路  Source: ethereum/solidity

Libraries can be seen as "implied" base contracts for any other contract. Because they cannot inherit and cannot be (explicitly) inherited from, this fits the inheritance system. Library functions are not taken into account in virtual method resolution, they can only be called explicitly via the already existing <BaseContract>.<functionName> way of selecting specific functions in virtual function overrides.

Because of that, it makes sense to allow contracts to call internal functions of libraries as if that library were a base contract of the caller. The calling convention will change to "internal" meaning in effect that the code of the library function (and anything called from therein) has to be included together with the code of the caller.

  • [x] make internal functions visible in library contract types and change calling convention to internal
  • [x] check that it is not possible to call function on library _instances_ (not exactly in scope but good to fix anyway)
  • [x] internal functions should not be part of the abi-interface
  • [x] check that it is possible to pass memory structs back and forth
  • [x] check that it is possible to return variably-sized memory data

Most helpful comment

To solidify (heh) my thoughts expressed in Gitter:

I believe 'inline' is the wrong keyword to use for this. In other languages, 'inline' is universally a request to the compiler that it apply a specific optimization strategy, taking the body of the inline function and inserting it at all its call sites. This is quite different from the meaning intended here, which is "link this function into the calling contract's code".

The former behavior is transparent to the user: whether or not the compiler honored the request, the code executes the same. The latter has real runtime implications on how values are passed, what return types are supported, and whether caller arguments can be mutated. Using 'inline' to mean this will confuse anyone familiar with an existing language that uses the term in its accustomed manner.

I would strongly suggest using the existing keyword 'internal'. The existing semantics of this keyword match what's desired: it may only be called from inside the contract or derived contracts, and exposes no external ABI. If you consider a contract that uses a library as the same sort of relationship as deriving from another contract, this isn't a problem. The 'private' keyword is still available to libraries wishing to disguise implementation details from their callers.

All 3 comments

I came across another issue with libraries, because they are and behave like a contract. Any method which would return something currently categorized as internal (such as a struct) is not allowed as external. Would be nice if the inline keyword would allow them (just as internal allows it).

@chriseth actually this question comes down to whether we consider a user of a library a derived contract or not.

To solidify (heh) my thoughts expressed in Gitter:

I believe 'inline' is the wrong keyword to use for this. In other languages, 'inline' is universally a request to the compiler that it apply a specific optimization strategy, taking the body of the inline function and inserting it at all its call sites. This is quite different from the meaning intended here, which is "link this function into the calling contract's code".

The former behavior is transparent to the user: whether or not the compiler honored the request, the code executes the same. The latter has real runtime implications on how values are passed, what return types are supported, and whether caller arguments can be mutated. Using 'inline' to mean this will confuse anyone familiar with an existing language that uses the term in its accustomed manner.

I would strongly suggest using the existing keyword 'internal'. The existing semantics of this keyword match what's desired: it may only be called from inside the contract or derived contracts, and exposes no external ABI. If you consider a contract that uses a library as the same sort of relationship as deriving from another contract, this isn't a problem. The 'private' keyword is still available to libraries wishing to disguise implementation details from their callers.

Was this page helpful?
0 / 5 - 0 ratings