Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

builtin.gno

3.25 Kb · 81 lines
 1package governor
 2
 3// The governor's own kinds act on the governor, and take it as an argument.
 4//
 5// They cannot hold one. A kind is a value in that governor's own registry, so a
 6// back-pointer is a reference cycle — and the VM refuses to finalize it:
 7//
 8//	unexpected unreal object: type=*gnolang.HeapItemValue ... isNewReal=true
 9//
10// Every test passed and the realm's own filetests wrote their storage; the
11// panic came afterwards, at persistence, which is the one place a cycle shows
12// up and the reason it survived being reasoned about. So the built-ins are
13// stateless values and the engine hands them the governor at the moment it
14// dispatches.
15//
16// The three methods mirror Kind's, minus the realm token: a built-in acts on
17// the registry rather than on the world, so it has no use for a sub-realm and
18// is never given one.
19type builtin interface {
20	Name() string
21	describe(g *Governor, payload string) string
22	check(g *Governor, payload string) error
23	run(g *Governor, dispatch Dispatch, payload string) error
24}
25
26// asBuiltin reports whether a kind is one of the governor's own.
27//
28// A type assertion rather than a name check. The reserved prefix says what a
29// kind is CALLED and Offer refuses it, but the dispatch has to be decided by
30// what a kind IS — a nominal check is the one thing an impostor cannot satisfy,
31// which is the same argument grc20's IsCanonicalTeller makes.
32func asBuiltin(k Kind) (builtin, bool) {
33	b, ok := k.(builtin)
34	return b, ok
35}
36
37// The Kind side of a built-in, so it satisfies the interface the registry
38// stores. Reached only through the engine, which checks asBuiltin first.
39func (k adoptKind) Describe(payload string) string { return "" }
40func (k adoptKind) Check(payload string) error     { return errBuiltinNeedsEngine }
41func (k adoptKind) Do(_ int, rlm realm, payload string) error {
42	return errBuiltinNeedsEngine
43}
44
45func (k retireKind) Describe(payload string) string { return "" }
46func (k retireKind) Check(payload string) error     { return errBuiltinNeedsEngine }
47func (k retireKind) Do(_ int, rlm realm, payload string) error {
48	return errBuiltinNeedsEngine
49}
50
51func (k rulesKind) Describe(payload string) string { return "" }
52func (k rulesKind) Check(payload string) error     { return errBuiltinNeedsEngine }
53func (k rulesKind) Do(_ int, rlm realm, payload string) error {
54	return errBuiltinNeedsEngine
55}
56
57func (k batchKind) Describe(payload string) string { return "" }
58func (k batchKind) Check(payload string) error     { return errBuiltinNeedsEngine }
59func (k batchKind) Do(_ int, rlm realm, payload string) error {
60	return errBuiltinNeedsEngine
61}
62
63// errBuiltinNeedsEngine is what these return if anything ever reaches them the
64// ordinary way. Unreachable through the engine, and an error rather than a
65// panic because a kind returning one is a proposal that fails cleanly.
66var errBuiltinNeedsEngine = govErr("a built-in kind has to be run by the governor that owns it")
67
68// checkKind and describeKind route to whichever half a kind has.
69func (g *Governor) checkKind(k Kind, payload string) error {
70	if b, ok := asBuiltin(k); ok {
71		return b.check(g, payload)
72	}
73	return k.Check(payload)
74}
75
76func (g *Governor) describeKind(k Kind, payload string) string {
77	if b, ok := asBuiltin(k); ok {
78		return b.describe(g, payload)
79	}
80	return k.Describe(payload)
81}