Skip to content
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

Add shift builtin (fix #4168). #4177

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions plutus-core/plutus-core/src/PlutusCore/Default/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import PlutusCore.Evaluation.Result
import PlutusCore.Pretty

import Crypto
import qualified Data.Bits as Bits
import qualified Data.ByteString as BS
import qualified Data.ByteString.Hash as Hash
import Data.Char
Expand All @@ -51,6 +52,7 @@ data DefaultFun
| EqualsInteger
| LessThanInteger
| LessThanEqualsInteger
| ShiftInteger
-- Bytestrings
| AppendByteString
| ConsByteString
Expand Down Expand Up @@ -178,6 +180,10 @@ instance uni ~ DefaultUni => ToBuiltinMeaning uni DefaultFun where
makeBuiltinMeaning
((<=) @Integer)
(runCostingFunTwoArguments . paramLessThanEqualsInteger)
toBuiltinMeaning ShiftInteger =
makeBuiltinMeaning
(\x i -> Bits.shift @Integer x (fromIntegral @Integer i))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess fromIntegral is incorrect here just like in case with ConsByteString and should be checked manually?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integer has a Bits instance, so why do we need to do this?

mempty -- TODO: add costing for ShiftInteger
-- Bytestrings
toBuiltinMeaning AppendByteString =
makeBuiltinMeaning
Expand Down Expand Up @@ -502,6 +508,8 @@ instance Flat DefaultFun where
MkNilData -> 49
MkNilPairData -> 50

ShiftInteger -> 51

decode = go =<< decodeBuiltin
where go 0 = pure AddInteger
go 1 = pure SubtractInteger
Expand Down Expand Up @@ -554,6 +562,7 @@ instance Flat DefaultFun where
go 48 = pure MkPairData
go 49 = pure MkNilData
go 50 = pure MkNilPairData
go 51 = pure ShiftInteger
go t = fail $ "Failed to decode builtin tag, got: " ++ show t

size _ n = n + builtinTagWidth
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(fun (con integer) (fun (con integer) (con integer)))
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ test_Integer = testCase "Integer" $ do
evals False LessThanEqualsInteger [cons @Integer 4001, cons @Integer 4000]
evals True EqualsInteger [cons @Integer (-101), cons @Integer (-101)]
evals False EqualsInteger [cons @Integer 0, cons @Integer 1]
evals @Integer 24 ShiftInteger [cons @Integer 3, cons @Integer 3]
evals @Integer 0 ShiftInteger [cons @Integer 3, cons @Integer (-3)]
evals @Integer (-2) ShiftInteger [cons @Integer (-3), cons @Integer (-1)]

-- | Test all string-like builtins
test_String :: TestTree
Expand Down
2 changes: 2 additions & 0 deletions plutus-tx-plugin/src/PlutusTx/Compiler/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ builtinNames = [
, 'Builtins.lessThanInteger
, 'Builtins.lessThanEqualsInteger
, 'Builtins.equalsInteger
, 'Builtins.shiftInteger

, 'Builtins.error

Expand Down Expand Up @@ -305,6 +306,7 @@ defineBuiltinTerms = do
defineBuiltinTerm 'Builtins.lessThanInteger $ mkBuiltin PLC.LessThanInteger
defineBuiltinTerm 'Builtins.lessThanEqualsInteger $ mkBuiltin PLC.LessThanEqualsInteger
defineBuiltinTerm 'Builtins.equalsInteger $ mkBuiltin PLC.EqualsInteger
defineBuiltinTerm 'Builtins.shiftInteger $ mkBuiltin PLC.ShiftInteger

-- Error
-- See Note [Delaying error]
Expand Down
10 changes: 10 additions & 0 deletions plutus-tx/src/PlutusTx/Builtins.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module PlutusTx.Builtins (
, lessThanInteger
, lessThanEqualsInteger
, equalsInteger
, shiftInteger
-- * Error
, error
-- * Data
Expand Down Expand Up @@ -217,6 +218,15 @@ lessThanEqualsInteger x y = fromBuiltin (BI.lessThanEqualsInteger (toBuiltin x)
equalsInteger :: Integer -> Integer -> Bool
equalsInteger x y = fromBuiltin (BI.equalsInteger (toBuiltin x) (toBuiltin y))

{-# INLINABLE shiftInteger #-}
{-| @'shiftInteger' x i@ shifts @x@ left by @i@ bits if @i@ is positive,
or right by @-i@ bits otherwise.
Right shifts perform sign extension on signed number types;
i.e. they fill the top bits with 1 if the @x@ is negative
and with 0 otherwise. -}
shiftInteger :: Integer -> Integer -> Integer
shiftInteger x y = fromBuiltin (BI.shiftInteger (toBuiltin x) (toBuiltin y))

{-# INLINABLE error #-}
-- | Aborts evaluation with an error.
error :: () -> a
Expand Down
5 changes: 5 additions & 0 deletions plutus-tx/src/PlutusTx/Builtins/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module PlutusTx.Builtins.Internal where
import Codec.Serialise
import Control.DeepSeq (NFData)
import qualified Crypto
import qualified Data.Bits as Bits
import qualified Data.ByteArray as BA
import Data.ByteString as BS
import qualified Data.ByteString.Hash as Hash
Expand Down Expand Up @@ -143,6 +144,10 @@ lessThanEqualsInteger = coerce ((<=) @Integer)
equalsInteger :: BuiltinInteger -> BuiltinInteger -> BuiltinBool
equalsInteger = coerce ((==) @Integer)

{-# NOINLINE shiftInteger #-}
shiftInteger :: BuiltinInteger -> BuiltinInteger -> BuiltinInteger
shiftInteger x i = Bits.shift @Integer x (fromIntegral @Integer i)

{-
BYTESTRING
-}
Expand Down