builtins.go raw
1 package mxtext
2
3 import (
4 "fmt"
5 "go/ast"
6 "go/parser"
7 "go/token"
8 )
9
10 // HasMoxieSecallocRefs reports whether any file in the package contains a
11 // reference to __moxie_secalloc, the stub the slice-literal rewriter emits
12 // for the `[]byte{:n, secure}` form. The loader uses this as an injection
13 // trigger so packages that ONLY use the secure-allocator literal (and none
14 // of the AST-level rewrites: pipe concat, byte compare, byte switch,
15 // add-assign) still get the builtin declarations injected.
16 func HasMoxieSecallocRefs(files []*ast.File) bool {
17 for _, f := range files {
18 found := false
19 ast.Inspect(f, func(n ast.Node) bool {
20 if found {
21 return false
22 }
23 if id, ok := n.(*ast.Ident); ok && id.Name == "__moxie_secalloc" {
24 found = true
25 return false
26 }
27 return true
28 })
29 if found {
30 return true
31 }
32 }
33 return false
34 }
35
36 // injectMoxieByteBuiltins parses __moxie_concat, __moxie_eq, __moxie_lt,
37 // and __moxie_secalloc declarations for the given package name. Called
38 // during the rewrite phase to make these functions available in any
39 // package that uses []byte ops or the secure-allocator literal syntax.
40 func InjectMoxieByteBuiltins(fset *token.FileSet, pkgName string) *ast.File {
41 src := fmt.Sprintf(`package %s
42
43 func __moxie_concat(a, b []byte) []byte {
44 panic("__moxie_concat: compiler failed to intercept")
45 }
46
47 func __moxie_eq(a, b []byte) bool {
48 panic("__moxie_eq: compiler failed to intercept")
49 }
50
51 func __moxie_lt(a, b []byte) bool {
52 panic("__moxie_lt: compiler failed to intercept")
53 }
54
55 func __moxie_secalloc(n int32) []byte {
56 panic("__moxie_secalloc: compiler failed to intercept")
57 }
58 `, pkgName)
59 f, err := parser.ParseFile(fset, "<moxie:builtins>", src, 0)
60 if err != nil {
61 return nil
62 }
63 return f
64 }
65