1
1
package compiler
2
2
3
3
import (
4
+ "context"
4
5
"fmt"
5
6
"log/slog"
6
7
"os"
7
8
8
9
extismSDK "github.com/extism/go-sdk"
10
+ "github.com/robbyt/go-polyscript/internal/helpers"
11
+ "github.com/robbyt/go-polyscript/machines/extism/compiler/internal/compile"
9
12
"github.com/tetratelabs/wazero"
10
13
)
11
14
12
- // Options holds the configuration for the Extism compiler
13
- type Options struct {
14
- EntryPoint string
15
- LogHandler slog.Handler
16
- Logger * slog.Logger
17
- EnableWASI bool
18
- RuntimeConfig wazero.RuntimeConfig
19
- HostFunctions []extismSDK.HostFunction
20
- }
21
-
22
- // FunctionalOption is a function that configures a Options instance
23
- type FunctionalOption func (* Options ) error
15
+ // FunctionalOption is a function that configures a Compiler instance
16
+ type FunctionalOption func (* Compiler ) error
24
17
25
18
// WithEntryPoint creates an option to set the entry point for Extism WASM modules
26
19
func WithEntryPoint (entryPoint string ) FunctionalOption {
27
- return func (cfg * Options ) error {
20
+ return func (c * Compiler ) error {
28
21
if entryPoint == "" {
29
22
return fmt .Errorf ("entry point cannot be empty" )
30
23
}
31
- cfg . EntryPoint = entryPoint
24
+ c . entryPointName = entryPoint
32
25
return nil
33
26
}
34
27
}
@@ -37,13 +30,13 @@ func WithEntryPoint(entryPoint string) FunctionalOption {
37
30
// This is the preferred option for logging configuration as it provides
38
31
// more flexibility through the slog.Handler interface.
39
32
func WithLogHandler (handler slog.Handler ) FunctionalOption {
40
- return func (cfg * Options ) error {
33
+ return func (c * Compiler ) error {
41
34
if handler == nil {
42
35
return fmt .Errorf ("log handler cannot be nil" )
43
36
}
44
- cfg . LogHandler = handler
37
+ c . logHandler = handler
45
38
// Clear logger if handler is explicitly set
46
- cfg . Logger = nil
39
+ c . logger = nil
47
40
return nil
48
41
}
49
42
}
@@ -52,86 +45,133 @@ func WithLogHandler(handler slog.Handler) FunctionalOption {
52
45
// This is less flexible than WithLogHandler but allows users to customize
53
46
// their logging group configuration.
54
47
func WithLogger (logger * slog.Logger ) FunctionalOption {
55
- return func (cfg * Options ) error {
48
+ return func (c * Compiler ) error {
56
49
if logger == nil {
57
50
return fmt .Errorf ("logger cannot be nil" )
58
51
}
59
- cfg . Logger = logger
52
+ c . logger = logger
60
53
// Clear handler if logger is explicitly set
61
- cfg . LogHandler = nil
54
+ c . logHandler = nil
62
55
return nil
63
56
}
64
57
}
65
58
66
59
// WithWASIEnabled creates an option to enable or disable WASI support
67
60
func WithWASIEnabled (enabled bool ) FunctionalOption {
68
- return func (cfg * Options ) error {
69
- cfg .EnableWASI = enabled
61
+ return func (c * Compiler ) error {
62
+ if c .options == nil {
63
+ c .options = & compile.Settings {}
64
+ }
65
+ c .options .EnableWASI = enabled
70
66
return nil
71
67
}
72
68
}
73
69
74
70
// WithRuntimeConfig creates an option to set a custom wazero runtime configuration
75
71
func WithRuntimeConfig (config wazero.RuntimeConfig ) FunctionalOption {
76
- return func (cfg * Options ) error {
72
+ return func (c * Compiler ) error {
77
73
if config == nil {
78
74
return fmt .Errorf ("runtime config cannot be nil" )
79
75
}
80
- cfg .RuntimeConfig = config
76
+ if c .options == nil {
77
+ c .options = & compile.Settings {}
78
+ }
79
+ c .options .RuntimeConfig = config
81
80
return nil
82
81
}
83
82
}
84
83
85
84
// WithHostFunctions creates an option to set additional host functions
86
85
func WithHostFunctions (funcs []extismSDK.HostFunction ) FunctionalOption {
87
- return func (cfg * Options ) error {
88
- cfg .HostFunctions = funcs
86
+ return func (c * Compiler ) error {
87
+ if c .options == nil {
88
+ c .options = & compile.Settings {}
89
+ }
90
+ c .options .HostFunctions = funcs
91
+ return nil
92
+ }
93
+ }
94
+
95
+ // WithContext creates an option to set a custom context for the Extism compiler.
96
+ func WithContext (ctx context.Context ) FunctionalOption {
97
+ return func (c * Compiler ) error {
98
+ if ctx == nil {
99
+ return fmt .Errorf ("context cannot be nil" )
100
+ }
101
+ c .ctx = ctx
89
102
return nil
90
103
}
91
104
}
92
105
93
- // ApplyDefaults sets the default values for a compilerConfig
94
- func ApplyDefaults ( cfg * Options ) {
106
+ // applyDefaults sets the default values for a compiler
107
+ func ( c * Compiler ) applyDefaults ( ) {
95
108
// Default to stderr for logging if neither handler nor logger specified
96
- if cfg . LogHandler == nil && cfg . Logger == nil {
97
- cfg . LogHandler = slog .NewTextHandler (os .Stderr , nil )
109
+ if c . logHandler == nil && c . logger == nil {
110
+ c . logHandler = slog .NewTextHandler (os .Stderr , nil )
98
111
}
99
112
100
- // Default entry point
101
- if cfg . EntryPoint == "" {
102
- cfg . EntryPoint = defaultEntryPoint
113
+ // Set default entry point
114
+ if c . entryPointName == "" {
115
+ c . entryPointName = defaultEntryPoint
103
116
}
104
117
105
- // Default WASI setting
106
- cfg .EnableWASI = true
118
+ // Initialize options struct if nil
119
+ if c .options == nil {
120
+ c .options = & compile.Settings {}
121
+ }
107
122
108
- // Default runtime config
109
- if cfg .RuntimeConfig == nil {
110
- cfg .RuntimeConfig = wazero .NewRuntimeConfig ()
123
+ // Set default runtime config if not already set
124
+ if c . options .RuntimeConfig == nil {
125
+ c . options .RuntimeConfig = wazero .NewRuntimeConfig ()
111
126
}
112
127
113
- // Default to empty host functions
114
- if cfg .HostFunctions == nil {
115
- cfg .HostFunctions = []extismSDK.HostFunction {}
128
+ // Set default host functions if not already set
129
+ if c .options .HostFunctions == nil {
130
+ c .options .HostFunctions = []extismSDK.HostFunction {}
131
+ }
132
+
133
+ // Default WASI to true (EnableWASI is a bool so we don't need to check if it's nil)
134
+ c .options .EnableWASI = true
135
+
136
+ // Default context
137
+ if c .ctx == nil {
138
+ c .ctx = context .Background ()
116
139
}
117
140
}
118
141
119
- // Validate checks if the configuration is valid
120
- func Validate (cfg * Options ) error {
142
+ // setupLogger configures the logger and handler based on the current state.
143
+ // This is idempotent and can be called multiple times during initialization.
144
+ func (c * Compiler ) setupLogger () {
145
+ if c .logger != nil {
146
+ // When a logger is explicitly set, extract its handler
147
+ c .logHandler = c .logger .Handler ()
148
+ } else {
149
+ // Otherwise use the handler (which might be default or custom) to create the logger
150
+ c .logHandler , c .logger = helpers .SetupLogger (c .logHandler , "extism" , "Compiler" )
151
+ }
152
+ }
153
+
154
+ // validate checks if the compiler configuration is valid
155
+ func (c * Compiler ) validate () error {
121
156
// Ensure we have either a logger or a handler
122
- if cfg . LogHandler == nil && cfg . Logger == nil {
157
+ if c . logHandler == nil && c . logger == nil {
123
158
return fmt .Errorf ("either log handler or logger must be specified" )
124
159
}
125
160
126
161
// Entry point must be non-empty
127
- if cfg . EntryPoint == "" {
162
+ if c . entryPointName == "" {
128
163
return fmt .Errorf ("entry point must be specified" )
129
164
}
130
165
131
166
// Runtime config cannot be nil
132
- if cfg .RuntimeConfig == nil {
167
+ if c . options == nil || c . options .RuntimeConfig == nil {
133
168
return fmt .Errorf ("runtime config cannot be nil" )
134
169
}
135
170
171
+ // Context cannot be nil
172
+ if c .ctx == nil {
173
+ return fmt .Errorf ("context cannot be nil" )
174
+ }
175
+
136
176
return nil
137
177
}
0 commit comments