Skip to content
Merged

Gloadss #3248

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
1 change: 1 addition & 0 deletions data/transactions/logic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ Some of these have immediate data in the byte or bytes after the opcode.
| `stores` | pop indexes A and B. store B to the Ath scratch space |
| `gload t i` | push Ith scratch space index of the Tth transaction in the current group |
| `gloads i` | push Ith scratch space index of the Xth transaction in the current group |
| `gloadss` | push Bth scratch space index of the Ath transaction in the current group |
| `gaid t` | push the ID of the asset or application created in the Tth transaction of the current group |
| `gaids` | push the ID of the asset or application created in the Xth transaction of the current group |

Expand Down
9 changes: 9 additions & 0 deletions data/transactions/logic/TEAL_opcodes.md
Original file line number Diff line number Diff line change
Expand Up @@ -1404,3 +1404,12 @@ bitlen interprets arrays as big-endian integers, unlike setbit/getbit
- push Xth LogicSig argument to stack
- LogicSigVersion >= 5
- Mode: Signature

## gloadss

- Opcode: 0xc4
- Pops: *... stack*, {uint64 A}, {uint64 B}
- Pushes: any
- push Bth scratch space index of the Ath transaction in the current group
- LogicSigVersion >= 6
- Mode: Application
5 changes: 4 additions & 1 deletion data/transactions/logic/assembler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,9 @@ const v6Nonsense = v5Nonsense + `
itxn_next
gitxn 4 CreatedAssetID
gitxna 3 Logs 12
int 0
dup
gloadss
`

var nonsense = map[uint64]string{
Expand All @@ -363,7 +366,7 @@ var compiled = map[uint64]string{
3: "032008b7a60cf8acd19181cf959a12f8acd19181cf951af8acd19181cf15f8acd191810f01020026050212340c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d024242047465737400320032013202320328292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e0102222324252104082209240a220b230c240d250e230f23102311231223132314181b1c2b171615400003290349483403350222231d4a484848482a50512a63222352410003420000432105602105612105270463484821052b62482b642b65484821052b2106662b21056721072b682b692107210570004848210771004848361c0037001a0031183119311b311d311e311f3120210721051e312131223123312431253126312731283129312a312b312c312d312e312f4478222105531421055427042106552105082106564c4d4b02210538212106391c0081e80780046a6f686e",
4: "042004010200b7a60c26040242420c68656c6c6f20776f726c6421208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292a0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482a50512a632223524100034200004322602261222b634848222862482864286548482228236628226724286828692422700048482471004848361c0037001a0031183119311b311d311e311f312024221e312131223123312431253126312731283129312a312b312c312d312e312f44782522531422542b2355220823564c4d4b0222382123391c0081e80780046a6f686e2281d00f24231f880003420001892223902291922394239593a0a1a2a3a4a5a6a7a8a9aaabacadae23af3a00003b003c003d8164",
5: "052004010002b7a60c26050242420c68656c6c6f20776f726c6421070123456789abcd208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292b0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482b50512a632223524100034200004322602261222704634848222862482864286548482228246628226723286828692322700048482371004848361c0037001a0031183119311b311d311e311f312023221e312131223123312431253126312731283129312a312b312c312d312e312f447825225314225427042455220824564c4d4b0222382124391c0081e80780046a6f686e2281d00f23241f880003420001892224902291922494249593a0a1a2a3a4a5a6a7a8a9aaabacadae24af3a00003b003c003d816472064e014f012a57000823810858235b235a2359b03139330039b1b200b322c01a23c1001a2323c21a23c3233e233f8120af06002a494905002a49490700b53a03",
6: "062004010002b7a60c26050242420c68656c6c6f20776f726c6421070123456789abcd208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292b0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482b50512a632223524100034200004322602261222704634848222862482864286548482228246628226723286828692322700048482371004848361c0037001a0031183119311b311d311e311f312023221e312131223123312431253126312731283129312a312b312c312d312e312f447825225314225427042455220824564c4d4b0222382124391c0081e80780046a6f686e2281d00f23241f880003420001892224902291922494249593a0a1a2a3a4a5a6a7a8a9aaabacadae24af3a00003b003c003d816472064e014f012a57000823810858235b235a2359b03139330039b1b200b322c01a23c1001a2323c21a23c3233e233f8120af06002a494905002a49490700b53a03b6b7043cb8033a0c}",
6: "062004010002b7a60c26050242420c68656c6c6f20776f726c6421070123456789abcd208dae2087fbba51304eb02b91f656948397a7946390e8cb70fc9ea4d95f92251d047465737400320032013202320380021234292929292b0431003101310231043105310731083109310a310b310c310d310e310f3111311231133114311533000033000133000233000433000533000733000833000933000a33000b33000c33000d33000e33000f3300113300123300133300143300152d2e01022581f8acd19181cf959a1281f8acd19181cf951a81f8acd19181cf1581f8acd191810f082209240a220b230c240d250e230f23102311231223132314181b1c28171615400003290349483403350222231d4a484848482b50512a632223524100034200004322602261222704634848222862482864286548482228246628226723286828692322700048482371004848361c0037001a0031183119311b311d311e311f312023221e312131223123312431253126312731283129312a312b312c312d312e312f447825225314225427042455220824564c4d4b0222382124391c0081e80780046a6f686e2281d00f23241f880003420001892224902291922494249593a0a1a2a3a4a5a6a7a8a9aaabacadae24af3a00003b003c003d816472064e014f012a57000823810858235b235a2359b03139330039b1b200b322c01a23c1001a2323c21a23c3233e233f8120af06002a494905002a49490700b53a03b6b7043cb8033a0c2349c4}",
}

func pseudoOp(opcode string) bool {
Expand Down
21 changes: 11 additions & 10 deletions data/transactions/logic/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,16 @@ var opDocByName = map[string]string{
"gitxn": "push field F of the Tth transaction in the last inner group",
"gitxna": "push Ith value of the array field F from the Tth transaction in the last inner group",

"global": "push value from globals to stack",
"load": "copy a value from scratch space to the stack. All scratch spaces are 0 at program start.",
"store": "pop value X. store X to the Ith scratch space",
"loads": "copy a value from the Xth scratch space to the stack. All scratch spaces are 0 at program start.",
"stores": "pop indexes A and B. store B to the Ath scratch space",
"gload": "push Ith scratch space index of the Tth transaction in the current group",
"gloads": "push Ith scratch space index of the Xth transaction in the current group",
"gaid": "push the ID of the asset or application created in the Tth transaction of the current group",
"gaids": "push the ID of the asset or application created in the Xth transaction of the current group",
"global": "push value from globals to stack",
"load": "copy a value from scratch space to the stack. All scratch spaces are 0 at program start.",
"store": "pop value X. store X to the Ith scratch space",
"loads": "copy a value from the Xth scratch space to the stack. All scratch spaces are 0 at program start.",
"stores": "pop indexes A and B. store B to the Ath scratch space",
"gload": "push Ith scratch space index of the Tth transaction in the current group",
"gloads": "push Ith scratch space index of the Xth transaction in the current group",
"gloadss": "push Bth scratch space index of the Ath transaction in the current group",
"gaid": "push the ID of the asset or application created in the Tth transaction of the current group",
"gaids": "push the ID of the asset or application created in the Xth transaction of the current group",

"bnz": "branch to TARGET if value X is not zero",
"bz": "branch to TARGET if value X is zero",
Expand Down Expand Up @@ -302,7 +303,7 @@ var OpGroups = map[string][]string{
"Byte Array Slicing": {"substring", "substring3", "extract", "extract3", "extract_uint16", "extract_uint32", "extract_uint64"},
"Byte Array Arithmetic": {"b+", "b-", "b/", "b*", "b<", "b>", "b<=", "b>=", "b==", "b!=", "b%"},
"Byte Array Logic": {"b|", "b&", "b^", "b~"},
"Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gaid", "gaids"},
"Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gloadss", "gaid", "gaids"},
"Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "dup", "dup2", "dig", "cover", "uncover", "swap", "select", "assert", "callsub", "retsub"},
"State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "log"},
"Inner Transactions": {"itxn_begin", "itxn_next", "itxn_field", "itxn_submit", "itxn", "itxna", "gitxn", "gitxna"},
Expand Down
24 changes: 24 additions & 0 deletions data/transactions/logic/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -2977,6 +2977,30 @@ func opGloads(cx *EvalContext) {
cx.stack[last] = scratchValue
}

func opGloadss(cx *EvalContext) {
last := len(cx.stack) - 1
prev := last - 1

gi := cx.stack[prev].Uint
if gi >= uint64(len(cx.TxnGroup)) {
cx.err = fmt.Errorf("gloads lookup TxnGroup[%d] but it only has %d", gi, len(cx.TxnGroup))
return
}
scratchIdx := cx.stack[last].Uint
if scratchIdx >= 256 {
cx.err = fmt.Errorf("gloadss scratch index >= 256 (%d)", scratchIdx)
return
}
Comment on lines +2984 to +2993
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems opGloadImpl does these checks as well, though with slightly different types? There may be a benefit to unifying these checks at some point, since that seems odd to me.

Copy link
Contributor

Choose a reason for hiding this comment

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

^ it looks alike with inputs from different places (and different types I suppose), would be nice to unify the checks too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think that, with some care, we could eliminate some repeat code. The "rule" right now is that any time a type is being narrowed before sending it to the Impl function, it is tested ahead of time. But, since unnarrowed types are not tested ahead of time, the Impl repeats the test. We could probably use wider types for the Impl() function, and only do the tests in there.

scratchValue, err := opGloadImpl(cx, int(gi), byte(scratchIdx), "gloadss")
if err != nil {
cx.err = err
return
}

cx.stack[prev] = scratchValue
cx.stack = cx.stack[:last]
}

func opConcat(cx *EvalContext) {
last := len(cx.stack) - 1
prev := last - 1
Expand Down
3 changes: 2 additions & 1 deletion data/transactions/logic/evalStateful_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2244,6 +2244,7 @@ func TestReturnTypes(t *testing.T) {
"store": "store 0",
"gload": "gload 0 0",
"gloads": "gloads 0",
"gloadss": "pop; pop; int 0; int 1; gloadss", // Needs txn index = 0 to work
"gaid": "gaid 0",
"dig": "dig 0",
"cover": "cover 0",
Expand Down Expand Up @@ -2325,7 +2326,7 @@ func TestReturnTypes(t *testing.T) {
require.Equal(
t,
len(spec.Returns), len(cx.stack),
fmt.Sprintf("\n%s%s expected to return %d values but stack has %d", ep.Trace.String(), spec.Name, len(spec.Returns), len(cx.stack)),
fmt.Sprintf("\n%s%s expected to return %d values but stack is %v", ep.Trace.String(), spec.Name, len(spec.Returns), cx.stack),
)
for i := 0; i < len(spec.Returns); i++ {
sp := len(cx.stack) - 1 - i
Expand Down
18 changes: 17 additions & 1 deletion data/transactions/logic/eval_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2468,6 +2468,7 @@ int 1`,
}
}

// TestGloads tests gloads and gloadss
func TestGloads(t *testing.T) {
partitiontest.PartitionTest(t)

Expand All @@ -2487,11 +2488,26 @@ int 0
gloads 0
byte "txn 1"
==
assert
int 1
gloads 1
byte "txn 2"
==
&&`
assert
int 0
int 0
gloadss
byte "txn 1"
==
assert
int 1
int 1
gloadss
byte "txn 2"
==
assert
int 1
`

sources := []string{source1, source2, source3}

Expand Down
3 changes: 2 additions & 1 deletion data/transactions/logic/opcodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ var OpSpecs = []OpSpec{
// Group scratch space access
{0x3a, "gload", opGload, asmDefault, disDefault, nil, oneAny, 4, runModeApplication, immediates("t", "i")},
{0x3b, "gloads", opGloads, asmDefault, disDefault, oneInt, oneAny, 4, runModeApplication, immediates("i")},
// Access creatable IDs
// Access creatable IDs (consider deprecating, as txn CreatedAssetID, CreatedApplicationID should be enough
Copy link
Contributor

@jasonpaulos jasonpaulos Nov 24, 2021

Choose a reason for hiding this comment

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

Do we have plans to make scratch slots accessible with transaction field types as well? They are pretty similar to logs, so it would make sense to me (at which point this opcode is less useful).

{0x3c, "gaid", opGaid, asmDefault, disDefault, nil, oneInt, 4, runModeApplication, immediates("t")},
{0x3d, "gaids", opGaids, asmDefault, disDefault, oneInt, oneInt, 4, runModeApplication, opDefault},

Expand Down Expand Up @@ -334,6 +334,7 @@ var OpSpecs = []OpSpec{
{0xc1, "gtxnas", opGtxnas, assembleGtxnas, disGtxn, oneInt, oneAny, 5, modeAny, immediates("t", "f")},
{0xc2, "gtxnsas", opGtxnsas, assembleGtxnsas, disTxn, twoInts, oneAny, 5, modeAny, immediates("f")},
{0xc3, "args", opArgs, asmDefault, disDefault, oneInt, oneBytes, 5, runModeSignature, opDefault},
{0xc4, "gloadss", opGloadss, asmDefault, disDefault, twoInts, oneAny, 6, runModeApplication, opDefault},
}

type sortByOpcode []OpSpec
Expand Down