Skip to content

Commit 48d8732

Browse files
committed
cue: maintain type cache per index (runtime)
Not doing so results in crashes in upcoming Go codec implementation. In general this seems like a good idea. Note that it may be better to do no caching at all, and leave it up to the go codec to cache. But for now we leave it until cuego is deprecated. Also hide Runtime.Context. Change-Id: I5179bc974503e78c8ae02f083e4b42a5ffb2cd39 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2709 Reviewed-by: Marcel van Lohuizen <[email protected]>
1 parent eac8f9a commit 48d8732

File tree

2 files changed

+14
-16
lines changed

2 files changed

+14
-16
lines changed

cue/build.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"encoding/gob"
2121
"path"
2222
"strconv"
23+
"sync"
2324

2425
"cuelang.org/go/cue/ast"
2526
"cuelang.org/go/cue/build"
@@ -33,8 +34,8 @@ import (
3334
// Any operation that involves two Values or Instances should originate from
3435
// the same Runtime.
3536
type Runtime struct {
36-
Context *build.Context // TODO: remove
37-
idx *index
37+
ctx *build.Context // TODO: remove
38+
idx *index
3839
}
3940

4041
func dummyLoad(token.Pos, string) *build.Instance { return nil }
@@ -131,7 +132,7 @@ func (inst *Instance) MarshalBinary() (b []byte, err error) {
131132
// name in position information. The source may import builtin packages. Use
132133
// Build to allow importing non-builtin packages.
133134
func (r *Runtime) Compile(filename string, source interface{}) (*Instance, error) {
134-
ctx := r.Context
135+
ctx := r.ctx
135136
if ctx == nil {
136137
ctx = build.NewContext()
137138
}
@@ -145,7 +146,7 @@ func (r *Runtime) Compile(filename string, source interface{}) (*Instance, error
145146
// CompileFile compiles the given source file into an Instance. The source may
146147
// import builtin packages. Use Build to allow importing non-builtin packages.
147148
func (r *Runtime) CompileFile(file *ast.File) (*Instance, error) {
148-
ctx := r.Context
149+
ctx := r.ctx
149150
if ctx == nil {
150151
ctx = build.NewContext()
151152
}
@@ -164,7 +165,7 @@ func (r *Runtime) CompileFile(file *ast.File) (*Instance, error) {
164165
// may import builtin packages. Use Build to allow importing non-builtin
165166
// packages.
166167
func (r *Runtime) CompileExpr(expr ast.Expr) (*Instance, error) {
167-
ctx := r.Context
168+
ctx := r.ctx
168169
if ctx == nil {
169170
ctx = build.NewContext()
170171
}
@@ -250,6 +251,9 @@ type index struct {
250251
offset label
251252
parent *index
252253
freeze bool
254+
255+
mutex sync.Mutex
256+
typeCache sync.Map // map[reflect.Type]evaluated
253257
}
254258

255259
const sharedOffset = 0x40000000

cue/go.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ import (
2222
"reflect"
2323
"sort"
2424
"strings"
25-
"sync"
2625

2726
"cuelang.org/go/cue/ast"
2827
"cuelang.org/go/cue/parser"
@@ -381,16 +380,11 @@ func toUint(ctx *context, src source, x uint64) evaluated {
381380
return n
382381
}
383382

384-
var (
385-
typeCache sync.Map // map[reflect.Type]evaluated
386-
mutex sync.Mutex
387-
)
388-
389383
func convertGoType(r *Runtime, t reflect.Type) value {
390384
ctx := r.index().newContext()
391385
// TODO: this can be much more efficient.
392-
mutex.Lock()
393-
defer mutex.Unlock()
386+
ctx.mutex.Lock()
387+
defer ctx.mutex.Unlock()
394388
return goTypeToValue(ctx, true, t)
395389
}
396390

@@ -405,7 +399,7 @@ var (
405399
// TODO: if this value will always be unified with a concrete type in Go, then
406400
// many of the fields may be omitted.
407401
func goTypeToValue(ctx *context, allowNullDefault bool, t reflect.Type) (e value) {
408-
if e, ok := typeCache.Load(t); ok {
402+
if e, ok := ctx.typeCache.Load(t); ok {
409403
return e.(value)
410404
}
411405

@@ -477,7 +471,7 @@ func goTypeToValue(ctx *context, allowNullDefault bool, t reflect.Type) (e value
477471
// resolve field tags to allow field tags to refer to the struct fields.
478472
tags := map[label]string{}
479473
obj := newStruct(baseValue{})
480-
typeCache.Store(t, obj)
474+
ctx.typeCache.Store(t, obj)
481475

482476
for i := 0; i < t.NumField(); i++ {
483477
f := t.Field(i)
@@ -559,7 +553,7 @@ func goTypeToValue(ctx *context, allowNullDefault bool, t reflect.Type) (e value
559553
store:
560554
// TODO: store error if not nil?
561555
if e != nil {
562-
typeCache.Store(t, e)
556+
ctx.typeCache.Store(t, e)
563557
}
564558
return e
565559
}

0 commit comments

Comments
 (0)