-
Notifications
You must be signed in to change notification settings - Fork 523
Add opcodes for dynamically indexing into Txn array fields #2847
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
Changes from all commits
fc520d0
f37928b
bb2cbf6
7c1f1ec
1cb18d5
d18878e
1bf8bfd
12b0bb8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1610,6 +1610,13 @@ func opArg2(cx *EvalContext) { | |
| func opArg3(cx *EvalContext) { | ||
| opArgN(cx, 3) | ||
| } | ||
| func opArgs(cx *EvalContext) { | ||
| last := len(cx.stack) - 1 | ||
| n := cx.stack[last].Uint | ||
| // Pop the index and push the result back on the stack. | ||
| cx.stack = cx.stack[:last] | ||
| opArgN(cx, n) | ||
| } | ||
|
|
||
| func branchTarget(cx *EvalContext) (int, error) { | ||
| offset := int16(uint16(cx.program[cx.pc+1])<<8 | uint16(cx.program[cx.pc+2])) | ||
|
|
@@ -2073,6 +2080,29 @@ func opTxna(cx *EvalContext) { | |
| cx.stack = append(cx.stack, sv) | ||
| } | ||
|
|
||
| func opTxnas(cx *EvalContext) { | ||
| last := len(cx.stack) - 1 | ||
|
|
||
| field := TxnField(cx.program[cx.pc+1]) | ||
| fs, ok := txnFieldSpecByField[field] | ||
| if !ok || fs.version > cx.version { | ||
| cx.err = fmt.Errorf("invalid txn field %d", field) | ||
| return | ||
| } | ||
| _, ok = txnaFieldSpecByField[field] | ||
| if !ok { | ||
| cx.err = fmt.Errorf("txnas unsupported field %d", field) | ||
| return | ||
| } | ||
| arrayFieldIdx := cx.stack[last].Uint | ||
| sv, err := cx.txnFieldToStack(&cx.Txn.Txn, field, arrayFieldIdx, cx.GroupIndex) | ||
| if err != nil { | ||
| cx.err = err | ||
| return | ||
| } | ||
| cx.stack[last] = sv | ||
| } | ||
|
|
||
| func opGtxn(cx *EvalContext) { | ||
| gtxid := int(uint(cx.program[cx.pc+1])) | ||
| if gtxid >= len(cx.TxnGroup) { | ||
|
|
@@ -2133,6 +2163,38 @@ func opGtxna(cx *EvalContext) { | |
| cx.stack = append(cx.stack, sv) | ||
| } | ||
|
|
||
| func opGtxnas(cx *EvalContext) { | ||
| last := len(cx.stack) - 1 | ||
|
|
||
| gtxid := int(cx.program[cx.pc+1]) | ||
| if gtxid >= len(cx.TxnGroup) { | ||
| cx.err = fmt.Errorf("gtxnas lookup TxnGroup[%d] but it only has %d", gtxid, len(cx.TxnGroup)) | ||
| return | ||
| } else if gtxid < 0 { | ||
| cx.err = fmt.Errorf("gtxnas lookup %d cannot be negative", gtxid) | ||
| return | ||
| } | ||
|
Comment on lines
+2170
to
+2176
Contributor
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. I'll fix this up when I do loads, stores, but just want to point out that we don't want to complain that the number is negative. In AVM, it isn't. It's only negative (potentially) because this code casted a big uint64 to an int, and that can give you a negative result.
Contributor
Author
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. Makes sense!
Contributor
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. PS, I liked the way you handled this in args a lot. There, you used uint64 mostly, and casted the len() calls instead of the stack argument. I think I will fix this stuff up that way, instead of the way I had been contemplating. |
||
| tx := &cx.TxnGroup[gtxid].Txn | ||
| field := TxnField(cx.program[cx.pc+2]) | ||
| fs, ok := txnFieldSpecByField[field] | ||
| if !ok || fs.version > cx.version { | ||
| cx.err = fmt.Errorf("invalid txn field %d", field) | ||
| return | ||
| } | ||
| _, ok = txnaFieldSpecByField[field] | ||
| if !ok { | ||
| cx.err = fmt.Errorf("gtxnas unsupported field %d", field) | ||
| return | ||
| } | ||
| arrayFieldIdx := cx.stack[last].Uint | ||
| sv, err := cx.txnFieldToStack(tx, field, arrayFieldIdx, gtxid) | ||
| if err != nil { | ||
| cx.err = err | ||
| return | ||
| } | ||
| cx.stack[last] = sv | ||
| } | ||
|
|
||
| func opGtxns(cx *EvalContext) { | ||
| last := len(cx.stack) - 1 | ||
| gtxid := int(cx.stack[last].Uint) | ||
|
|
@@ -2195,6 +2257,40 @@ func opGtxnsa(cx *EvalContext) { | |
| cx.stack[last] = sv | ||
| } | ||
|
|
||
| func opGtxnsas(cx *EvalContext) { | ||
| last := len(cx.stack) - 1 | ||
| prev := last - 1 | ||
|
|
||
| gtxid := int(cx.stack[prev].Uint) | ||
| if gtxid >= len(cx.TxnGroup) { | ||
| cx.err = fmt.Errorf("gtxnsas lookup TxnGroup[%d] but it only has %d", gtxid, len(cx.TxnGroup)) | ||
| return | ||
| } else if gtxid < 0 { | ||
| cx.err = fmt.Errorf("gtxnsas lookup %d cannot be negative", gtxid) | ||
| return | ||
| } | ||
| tx := &cx.TxnGroup[gtxid].Txn | ||
| field := TxnField(cx.program[cx.pc+1]) | ||
| fs, ok := txnFieldSpecByField[field] | ||
| if !ok || fs.version > cx.version { | ||
| cx.err = fmt.Errorf("invalid txn field %d", field) | ||
| return | ||
| } | ||
| _, ok = txnaFieldSpecByField[field] | ||
| if !ok { | ||
| cx.err = fmt.Errorf("gtxnsas unsupported field %d", field) | ||
| return | ||
| } | ||
| arrayFieldIdx := cx.stack[last].Uint | ||
| sv, err := cx.txnFieldToStack(tx, field, arrayFieldIdx, gtxid) | ||
| if err != nil { | ||
| cx.err = err | ||
| return | ||
| } | ||
| cx.stack[prev] = sv | ||
| cx.stack = cx.stack[:last] | ||
| } | ||
|
|
||
| func opGaidImpl(cx *EvalContext, groupIdx int, opName string) (sv stackValue, err error) { | ||
| if groupIdx >= len(cx.TxnGroup) { | ||
| err = fmt.Errorf("%s lookup TxnGroup[%d] but it only has %d", opName, groupIdx, len(cx.TxnGroup)) | ||
|
|
||
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.
Let's try to use %s and spec.Name as often as possible.
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.
Agreed - I think we can potentially save ourselves time in the future by doing this.