diff --git a/core/vm/evm.go b/core/vm/evm.go index 2b9940297c84..ed57562c43ab 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -35,7 +35,7 @@ func (sel Selector) String() string { if sel == "" { return "interpreter" } - return "unknown" + return string(sel) } // MarshalText implements encoding.TextMarshaler interface. @@ -52,7 +52,17 @@ func (sel *Selector) UnmarshalText(text []byte) error { *sel = "" return nil } - return fmt.Errorf(`unknown option %q, want "interpreter"`, text) + createMu.Lock() + defer createMu.Unlock() + if evmcInstance != nil { + return fmt.Errorf("only single EVMC module is currently supported") + } + instance, err := initEvmcModule(string(text)) + if err != nil { + return err + } + evmcInstance = instance + return nil } // emptyCodeHash is used by create to ensure deployment is disallowed to already diff --git a/core/vm/evmc.go b/core/vm/evmc.go index 84aedcf4dca1..c08c2c86a4d8 100644 --- a/core/vm/evmc.go +++ b/core/vm/evmc.go @@ -29,7 +29,6 @@ import ( "github.com/ethereum/evmc/bindings/go/evmc" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" ) @@ -47,48 +46,45 @@ var ( evmcInstance *evmc.Instance // The EVMC VM instance. ) -// NewEVMC creates new EVMC-based VM execution context. -func NewEVMC(config string, env *EVM) *EVMC { - createMu.Lock() - defer createMu.Unlock() - - if evmcInstance == nil { - options := strings.Split(config, ",") - path := options[0] +func initEvmcModule(config string) (*evmc.Instance, error) { + options := strings.Split(config, ",") + path := options[0] - if path == "" { - panic("EVMC VM path not provided, set --vm.(evm|ewasm)=/path/to/vm") - } + instance, err := evmc.Load(path) + if err != nil { + return nil, err + } - var err error - evmcInstance, err = evmc.Load(path) - if err != nil { - panic(err.Error()) - } - log.Info("EVMC VM loaded", "name", evmcInstance.Name(), "version", evmcInstance.Version(), "path", path) - - for _, option := range options[1:] { - if idx := strings.Index(option, "="); idx >= 0 { - name := option[:idx] - value := option[idx+1:] - err := evmcInstance.SetOption(name, value) - if err == nil { - log.Info("EVMC VM option set", "name", name, "value", value) - } else { - log.Warn("EVMC VM option setting failed", "name", name, "error", err) - } + // log.Info("EVMC VM loaded", "name", instance.Name(), "version", instance.Version(), "path", path) + fmt.Printf("EVMC VM loaded %s %s %s\n", instance.Name(), instance.Version(), path) + + for _, option := range options[1:] { + if idx := strings.Index(option, "="); idx >= 0 { + name := option[:idx] + value := option[idx+1:] + err := instance.SetOption(name, value) + if err == nil { + // log.Info("EVMC VM option set", "name", name, "value", value) + fmt.Printf("EVMC VM option set %s=%s\n", name, value) + } else { + return nil, fmt.Errorf("EVMC VM option setting failed '%s=%s'", name, value) } } + } - evm1Cap := evmcInstance.HasCapability(evmc.CapabilityEVM1) - ewasmCap := evmcInstance.HasCapability(evmc.CapabilityEWASM) - log.Info("EVMC VM capabilities", "evm1", evm1Cap, "ewasm", ewasmCap) + evm1Cap := instance.HasCapability(evmc.CapabilityEVM1) + ewasmCap := instance.HasCapability(evmc.CapabilityEWASM) + // log.Info("EVMC VM capabilities", "evm1", evm1Cap, "ewasm", ewasmCap) + fmt.Printf("EVMC VM capabilities: evm=%t ewasm=%t\n", evm1Cap, ewasmCap) - evmcConfig = config // Remember the config. - } else if evmcConfig != config { - log.Error("New EVMC VM requested", "newconfig", config, "oldconfig", evmcConfig) - } + return instance, nil +} +// NewEVMC creates new EVMC-based VM execution context. +func NewEVMC(config string, env *EVM) *EVMC { + if evmcInstance == nil { + panic("EVMC module not loaded") + } return &EVMC{evmcInstance, env, false} }