github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/internal/buildcfg/exp.go (about)

     1  // Copyright 2021 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE.assembler file.
     4  
     5  package buildcfg
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"strings"
    11  
    12  	"github.com/Rookout/GoSDK/pkg/services/assembler/internal/goexperiment"
    13  )
    14  
    15  
    16  
    17  type ExperimentFlags struct {
    18  	goexperiment.Flags
    19  	baseline goexperiment.Flags
    20  }
    21  
    22  
    23  
    24  
    25  
    26  
    27  
    28  
    29  
    30  
    31  var Experiment ExperimentFlags = func() ExperimentFlags {
    32  	flags, err := ParseGOEXPERIMENT(GOOS, GOARCH, envOr("GOEXPERIMENT", ""))
    33  	if err != nil {
    34  		Error = err
    35  		return ExperimentFlags{}
    36  	}
    37  	return *flags
    38  }()
    39  
    40  
    41  
    42  const DefaultGOEXPERIMENT = ""
    43  
    44  
    45  
    46  
    47  
    48  
    49  
    50  
    51  var FramePointerEnabled = GOARCH == "amd64" || GOARCH == "arm64"
    52  
    53  
    54  
    55  
    56  
    57  
    58  func ParseGOEXPERIMENT(goos, goarch, goexp string) (*ExperimentFlags, error) {
    59  	
    60  	
    61  	
    62  	
    63  	var regabiSupported, regabiAlwaysOn bool
    64  	switch goarch {
    65  	case "amd64", "arm64", "ppc64le", "ppc64", "riscv64":
    66  		regabiAlwaysOn = true
    67  		regabiSupported = true
    68  	}
    69  
    70  	baseline := goexperiment.Flags{
    71  		RegabiWrappers:   regabiSupported,
    72  		RegabiArgs:       regabiSupported,
    73  		CoverageRedesign: true,
    74  	}
    75  
    76  	
    77  	flags := &ExperimentFlags{
    78  		Flags:    baseline,
    79  		baseline: baseline,
    80  	}
    81  
    82  	
    83  	
    84  	
    85  	if goexp != "" {
    86  		
    87  		names := make(map[string]func(bool))
    88  		rv := reflect.ValueOf(&flags.Flags).Elem()
    89  		rt := rv.Type()
    90  		for i := 0; i < rt.NumField(); i++ {
    91  			field := rv.Field(i)
    92  			names[strings.ToLower(rt.Field(i).Name)] = field.SetBool
    93  		}
    94  
    95  		
    96  		
    97  		
    98  		
    99  		names["regabi"] = func(v bool) {
   100  			flags.RegabiWrappers = v
   101  			flags.RegabiArgs = v
   102  		}
   103  
   104  		
   105  		for _, f := range strings.Split(goexp, ",") {
   106  			if f == "" {
   107  				continue
   108  			}
   109  			if f == "none" {
   110  				
   111  				
   112  				
   113  				flags.Flags = goexperiment.Flags{}
   114  				continue
   115  			}
   116  			val := true
   117  			if strings.HasPrefix(f, "no") {
   118  				f, val = f[2:], false
   119  			}
   120  			set, ok := names[f]
   121  			if !ok {
   122  				return nil, fmt.Errorf("unknown GOEXPERIMENT %s", f)
   123  			}
   124  			set(val)
   125  		}
   126  	}
   127  
   128  	if regabiAlwaysOn {
   129  		flags.RegabiWrappers = true
   130  		flags.RegabiArgs = true
   131  	}
   132  	
   133  	if !regabiSupported {
   134  		flags.RegabiWrappers = false
   135  		flags.RegabiArgs = false
   136  	}
   137  	
   138  	if flags.RegabiArgs && !flags.RegabiWrappers {
   139  		return nil, fmt.Errorf("GOEXPERIMENT regabiargs requires regabiwrappers")
   140  	}
   141  	return flags, nil
   142  }
   143  
   144  
   145  
   146  func (exp *ExperimentFlags) String() string {
   147  	return strings.Join(expList(&exp.Flags, &exp.baseline, false), ",")
   148  }
   149  
   150  
   151  
   152  
   153  
   154  func expList(exp, base *goexperiment.Flags, all bool) []string {
   155  	var list []string
   156  	rv := reflect.ValueOf(exp).Elem()
   157  	var rBase reflect.Value
   158  	if base != nil {
   159  		rBase = reflect.ValueOf(base).Elem()
   160  	}
   161  	rt := rv.Type()
   162  	for i := 0; i < rt.NumField(); i++ {
   163  		name := strings.ToLower(rt.Field(i).Name)
   164  		val := rv.Field(i).Bool()
   165  		baseVal := false
   166  		if base != nil {
   167  			baseVal = rBase.Field(i).Bool()
   168  		}
   169  		if all || val != baseVal {
   170  			if val {
   171  				list = append(list, name)
   172  			} else {
   173  				list = append(list, "no"+name)
   174  			}
   175  		}
   176  	}
   177  	return list
   178  }
   179  
   180  
   181  
   182  func (exp *ExperimentFlags) Enabled() []string {
   183  	return expList(&exp.Flags, nil, false)
   184  }
   185  
   186  
   187  
   188  func (exp *ExperimentFlags) All() []string {
   189  	return expList(&exp.Flags, nil, true)
   190  }