@@ -565,6 +565,8 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
565
565
switch {
566
566
case n .action != aAssign :
567
567
// Do not optimize assign combined with another operator.
568
+ case src .rval .IsValid ():
569
+ // Do not skip assign operation when setting from a constant value.
568
570
case isMapEntry (dest ):
569
571
// Setting a map entry needs an additional step, do not optimize.
570
572
// As we only write, skip the default useless getIndexMap dest action.
@@ -855,13 +857,15 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
855
857
wireChild (n )
856
858
switch {
857
859
case interp .isBuiltinCall (n ):
858
- err = check .builtin (n .child [0 ].ident , n , n .child [1 :], n .action == aCallSlice )
860
+ c0 := n .child [0 ]
861
+ bname := c0 .ident
862
+ err = check .builtin (bname , n , n .child [1 :], n .action == aCallSlice )
859
863
if err != nil {
860
864
break
861
865
}
862
866
863
- n .gen = n . child [ 0 ] .sym .builtin
864
- n . child [ 0 ] .typ = & itype {cat : builtinT }
867
+ n .gen = c0 .sym .builtin
868
+ c0 .typ = & itype {cat : builtinT }
865
869
if n .typ , err = nodeType (interp , sc , n ); err != nil {
866
870
return
867
871
}
@@ -872,10 +876,18 @@ func (interp *Interpreter) cfg(root *node, importPath string) ([]*node, error) {
872
876
case n .anc .kind == returnStmt :
873
877
// Store result directly to frame output location, to avoid a frame copy.
874
878
n .findex = 0
879
+ case bname == "cap" && isInConstOrTypeDecl (n ):
880
+ capConst (n )
881
+ n .findex = notInFrame
882
+ n .gen = nop
883
+ case bname == "len" && isInConstOrTypeDecl (n ):
884
+ lenConst (n )
885
+ n .findex = notInFrame
886
+ n .gen = nop
875
887
default :
876
888
n .findex = sc .add (n .typ )
877
889
}
878
- if op , ok := constBltn [n . child [ 0 ]. ident ]; ok && n .anc .action != aAssign {
890
+ if op , ok := constBltn [bname ]; ok && n .anc .action != aAssign {
879
891
op (n ) // pre-compute non-assigned constant :
880
892
}
881
893
case n .child [0 ].isType (sc ):
@@ -2326,6 +2338,20 @@ func isRecursiveField(n *node) bool {
2326
2338
return false
2327
2339
}
2328
2340
2341
+ func isInConstOrTypeDecl (n * node ) bool {
2342
+ anc := n .anc
2343
+ for anc != nil {
2344
+ switch anc .kind {
2345
+ case constDecl , typeDecl :
2346
+ return true
2347
+ case varDecl , funcDecl :
2348
+ return false
2349
+ }
2350
+ anc = anc .anc
2351
+ }
2352
+ return false
2353
+ }
2354
+
2329
2355
// isNewDefine returns true if node refers to a new definition.
2330
2356
func isNewDefine (n * node , sc * scope ) bool {
2331
2357
if n .ident == "_" {
0 commit comments