-
Notifications
You must be signed in to change notification settings - Fork 9
Implement interfaceId via new type(C).publicMethods builtin
#462
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
axic
wants to merge
8
commits into
argotorg:main
Choose a base branch
from
axic:interface-id
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
3d0e1fd
Add `type(C).publicMethods` primitive and interface-id computation
claude 1f0fbcd
Fix interfaceid example: construct uint256(0) instead of bare literal
claude 50072b4
Use concrete SelectorArray instead of generic DynArray for publicMethods
claude 6ca1bab
Simplify test
axic 584a188
Formatting
axic 6f840bb
Align publicMethods feature with main's funIsPublic FunDef
claude 67c894b
Redesign publicMethods as a PublicMethods type class over Proxy(Method)
claude e968643
PublicMethods: drop length, constrain head as Method(...) like compute
claude File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,8 @@ | |
| module Solcore.Desugarer.ContractDispatch | ||
| ( contractDispatchDesugarer, | ||
| contractDispatchTopDecls, | ||
| nameTypeName, | ||
| publicMethodTypes, | ||
| ) | ||
| where | ||
|
|
||
|
|
@@ -259,6 +261,45 @@ mkNameInst (DataTy dname [] []) fname = | |
| } | ||
| mkNameInst dt _ = error ("Internal Error: unexpected name type structure: " <> show dt) | ||
|
|
||
| -- | The 'Method' type (as used by the dispatcher) for each public, | ||
| -- fully-typed method of a contract, in dispatch order. Used by the | ||
| -- @type(C).publicMethods@ primitive to compute interface ids: each 'Method' | ||
| -- type has a 'Selector' instance (which reuses 'sigStr'), so the selectors can | ||
| -- be derived from these types without reimplementing any hashing in the | ||
| -- compiler. The payability and return types are carried faithfully; the | ||
| -- function ('fn') field is irrelevant to the selector and is filled with a | ||
| -- 'word' placeholder. The fallback and any non-fully-typed methods are | ||
| -- skipped. | ||
| publicMethodTypes :: Contract Name -> [Ty] | ||
| publicMethodTypes (Contract cname _ cdecls) = | ||
| mapMaybe methodTy (mapMaybe unwrapSigs cdecls) | ||
| where | ||
| -- skip the optional fallback function and non-public methods, mirroring the | ||
| -- dispatch table built in 'genMainFn' | ||
| unwrapSigs (CFunDecl (FunDef True s _)) | ||
| | sigName s == fallbackName = Nothing | ||
| | otherwise = Just s | ||
| unwrapSigs _ = Nothing | ||
|
|
||
| methodTy (Signature _ _ fname fargs _ (Just ret) payable) | ||
| | all isTyped fargs = | ||
| Just $ | ||
| TyCon | ||
| "Method" | ||
| [ TyCon (nameTypeName cname fname) [], | ||
| TyCon (if payable then "Payable" else "NonPayable") [], | ||
| tupleTyFromList (mapMaybe getTy fargs), | ||
| ret, | ||
| word | ||
| ] | ||
| methodTy _ = Nothing | ||
|
|
||
| isTyped (Typed {}) = True | ||
| isTyped (Untyped {}) = False | ||
|
|
||
| getTy (Typed _ _ t) = Just t | ||
| getTy (Untyped {}) = Nothing | ||
|
Comment on lines
+297
to
+301
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This repeats code from |
||
|
|
||
| --- Util --- | ||
|
|
||
| proxyTy :: Ty -> Ty | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| {-# LANGUAGE OverloadedStrings #-} | ||
|
|
||
| -- | | ||
| -- Module : Solcore.Desugarer.PublicMethods | ||
| -- Description : Implements the `type(C).publicMethods` primitive | ||
| -- | ||
| -- The parser/name-resolver turns `type(C).publicMethods` into a call to a | ||
| -- per-contract helper function (see 'publicMethodsTagName'). This pass | ||
| -- generates the body of that helper for every contract whose primitive is | ||
| -- actually used. | ||
| -- | ||
| -- The helper hands back a type-level token — @Proxy(methods)@ — describing the | ||
| -- contract's public methods as a right-nested tuple terminated by @()@: | ||
| -- | ||
| -- @Proxy((Method(...), (Method(...), ... ())))@ | ||
| -- | ||
| -- Each element carries the very same @Method(name,payability,args,rets,fn)@ | ||
| -- typing consumed by @Selector.compute@ (see @std/dispatch.solc@), so no | ||
| -- selector hashing leaks into the compiler. Walking that tuple — counting the | ||
| -- methods (@length@) and XOR-folding their selectors into an interface id — is | ||
| -- the @PublicMethods@ type class in @std/dispatch.solc@; the compiler only | ||
| -- exposes the method list, never the iteration or hashing. | ||
| -- | ||
| -- This must run BEFORE contract dispatch generation, which produces the | ||
| -- per-method @DispatchNameTy_*@ name types (and their @SigString@ instances) | ||
| -- that the method tuple refers to. | ||
| module Solcore.Desugarer.PublicMethods | ||
| ( publicMethodsDesugarer, | ||
| publicMethodsTopDecls, | ||
| ) | ||
| where | ||
|
|
||
| import Data.Generics (listify) | ||
| import Data.List (isPrefixOf) | ||
| import Solcore.Desugarer.ContractDispatch (publicMethodTypes) | ||
| import Solcore.Frontend.Syntax | ||
| import Solcore.Frontend.Syntax.NameResolution (publicMethodsTagName) | ||
| import Solcore.Primitives.Primitives (tupleTyFromList, unit) | ||
|
|
||
| publicMethodsDesugarer :: CompUnit Name -> CompUnit Name | ||
| publicMethodsDesugarer (CompUnit ims topdecls) = | ||
| CompUnit ims (publicMethodsTopDecls topdecls) | ||
|
|
||
| publicMethodsTopDecls :: [TopDecl Name] -> [TopDecl Name] | ||
| publicMethodsTopDecls topdecls = topdecls ++ helpers | ||
| where | ||
| -- every contract paired with the helper name its `publicMethods` primitive | ||
| -- would call | ||
| contractsByTag = | ||
| [(publicMethodsTagName cname, c) | TContr c@(Contract cname _ _) <- topdecls] | ||
|
|
||
| -- helper names actually referenced by a `type(C).publicMethods` call | ||
| referenced = | ||
| [fn | Call Nothing fn [] <- listify isTagCall topdecls] | ||
|
|
||
| helpers = | ||
| [ genPublicMethodsFn c | ||
| | (tag, c) <- contractsByTag, | ||
| tag `elem` referenced | ||
| ] | ||
|
|
||
| isTagCall :: Exp Name -> Bool | ||
| isTagCall (Call Nothing fn []) = isTagName fn | ||
| isTagCall _ = False | ||
|
|
||
| isTagName :: Name -> Bool | ||
| isTagName (Name s) = "$publicMethods$" `isPrefixOf` s | ||
| isTagName _ = False | ||
|
|
||
| -- | Generate the helper that yields a contract's public-method tuple as a | ||
| -- @Proxy@ type token. The tuple is right-nested and terminated by @()@ so the | ||
| -- @PublicMethods@ instances in @std/dispatch.solc@ only need a @()@ base case | ||
| -- and an @(n, m)@ recursive case (no special single-method case). | ||
| genPublicMethodsFn :: Contract Name -> TopDecl Name | ||
| genPublicMethodsFn c@(Contract cname _ _) = | ||
| TFunDef (FunDef False sig body) | ||
| where | ||
| -- the public methods, plus a `()` terminator for the tuple | ||
| methodsTuple = tupleTyFromList (publicMethodTypes c ++ [unit]) | ||
| proxyTy = TyCon "Proxy" [methodsTuple] | ||
|
|
||
| sig = | ||
| Signature | ||
| { sigVars = [], | ||
| sigContext = [], | ||
| sigName = publicMethodsTagName cname, | ||
| sigParams = [], | ||
| sigRetComptime = False, | ||
| sigReturn = Just proxyTy, | ||
| sigPayable = False | ||
| } | ||
|
|
||
| -- return Proxy : Proxy((Method(...), (Method(...), ... ()))); | ||
| body = [Return (TyExp (Con "Proxy" []) proxyTy)] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This repeats code from
genMainFn