tests.gno
3.30 Kb · 151 lines
1package tests
2
3import (
4 "chain/runtime"
5 "chain/runtime/unsafe"
6
7 "gno.land/p/demo/nestedpkg"
8 rsubtests "gno.land/r/tests/vm/subtests"
9)
10
11var counter int
12
13func IncCounter(cur realm) {
14 counter++
15}
16
17func Counter(cur realm) int {
18 return counter
19}
20
21func CurrentRealmPath(cur realm) string {
22 return unsafe.CurrentRealm().PkgPath()
23}
24
25var initOriginCaller = unsafe.OriginCaller()
26
27func InitOriginCaller(cur realm) address {
28 return initOriginCaller
29}
30
31func CallAssertOriginCall(cur realm) {
32 runtime.AssertOriginCall()
33}
34
35func CallIsOriginCall(cur realm) bool {
36 // XXX: consider return !unsafe.PreviousRealm().IsCode()
37 return unsafe.PreviousRealm().IsUser()
38}
39
40func CallSubtestsAssertOriginCall(cur realm) {
41 rsubtests.CallAssertOriginCall(cross(cur))
42}
43
44func CallSubtestsIsOriginCall(cur realm) bool {
45 return rsubtests.CallIsOriginCall(cross(cur))
46}
47
48//----------------------------------------
49// Test structure to ensure cross-realm modification is prevented.
50
51type TestRealmObject struct {
52 Field string
53}
54
55var TestRealmObjectValue TestRealmObject
56
57// NewTestRealmObject returns a fresh heap-allocated TestRealmObject.
58// Non-crossing — relies on borrow rule #1 to set m.Realm = /r/tests/vm
59// inside the body so the composite literal passes checkConstructionTime.
60func NewTestRealmObject() *TestRealmObject {
61 return &TestRealmObject{Field: "initial"}
62}
63
64func ModifyTestRealmObject(cur realm, t *TestRealmObject) {
65 t.Field += "_modified"
66}
67
68func (t *TestRealmObject) Modify() {
69 t.Field += "_modified"
70}
71
72//----------------------------------------
73// Test helpers to test a particular realm bug.
74
75type TestNode struct {
76 Name string
77 Child *TestNode
78}
79
80var (
81 gTestNode1 *TestNode
82 gTestNode2 *TestNode
83 gTestNode3 *TestNode
84)
85
86func InitTestNodes(cur realm) {
87 gTestNode1 = &TestNode{Name: "first"}
88 gTestNode2 = &TestNode{Name: "second", Child: &TestNode{Name: "second's child"}}
89}
90
91func ModTestNodes(cur realm) {
92 tmp := &TestNode{}
93 tmp.Child = gTestNode2.Child
94 gTestNode3 = tmp // set to new-real
95 // gTestNode1 = tmp.Child // set back to original is-real
96 gTestNode3 = nil // delete.
97}
98
99func PrintTestNodes() {
100 println(gTestNode2.Child.Name)
101}
102
103func GetPreviousRealm(cur realm) runtime.Realm {
104 return unsafe.PreviousRealm()
105}
106
107func GetRSubtestsPreviousRealm(cur realm) runtime.Realm {
108 return rsubtests.GetPreviousRealm(cross(cur))
109}
110
111func Exec(fn func()) {
112 // no realm switching.
113 fn()
114}
115
116// ExecRlm mirrors Exec but threads the caller's rlm into the callback
117// so the callback can use `cross(rlm)` instead of bare `cross`.
118func ExecRlm(_ int, rlm realm, fn func(_ int, rlm realm)) {
119 fn(0, rlm)
120}
121
122func ExecSwitch(cur realm, fn func()) {
123 fn()
124}
125
126// ExecSwitchRlm is the rlm-threaded variant of ExecSwitch — crosses
127// into this realm and passes the callee's cur to the callback so
128// the callback can `cross(rlm)` against the switched realm.
129func ExecSwitchRlm(cur realm, fn func(_ int, rlm realm)) {
130 fn(0, cur)
131}
132
133func IsCallerSubPath(cur realm) bool {
134 return nestedpkg.IsCallerSubPath(0, cur)
135}
136
137func IsCallerParentPath(cur realm) bool {
138 return nestedpkg.IsCallerParentPath(0, cur)
139}
140
141func HasCallerSameNamespace(cur realm) bool {
142 return nestedpkg.IsSameNamespace(0, cur)
143}
144
145func BankerOriginSend(cur realm) string {
146 return unsafe.OriginSend().String()
147}
148
149func RTestsOriginSend(cur realm) string {
150 return rsubtests.BankerOriginSend(cross(cur))
151}