-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsolc.go
105 lines (91 loc) · 2.08 KB
/
solc.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package gsolc
import (
"encoding/json"
"os"
"sync"
"github.com/hashicorp/go-version"
v8 "rogchap.com/v8go"
)
type Compiler struct {
isolate *v8.Isolate
ctx *v8.Context
mux *sync.Mutex
compiler *v8.Value
ver *version.Version
}
func NewFromFile(file, ver string) (*Compiler, error) {
v, err := version.NewVersion(ver)
if err != nil {
return nil, err
}
var (
isolate = v8.NewIsolate()
ctx = v8.NewContext(isolate)
c = &Compiler{
isolate: isolate,
ctx: ctx,
ver: v,
mux: &sync.Mutex{},
}
)
soljson, err := os.ReadFile(file)
if err != nil {
return nil, err
}
if err = c.init(string(soljson)); err != nil {
return nil, err
}
return c, nil
}
func (c *Compiler) init(wasmScript string) error {
var err error
if _, err = c.ctx.RunScript(wasmScript, "main.js"); err != nil {
return err
}
var (
ver6, _ = version.NewVersion("0.6.0")
ver5, _ = version.NewVersion("0.5.0")
)
if c.ver.LessThan(ver5) {
c.compiler, err = c.ctx.RunScript("Module.cwrap('compileStandard', 'string', ['string', 'number'])",
"wrap_compile.js")
} else if c.ver.GreaterThanOrEqual(ver5) && c.ver.LessThan(ver6) {
c.compiler, err = c.ctx.RunScript("Module.cwrap('solidity_compile', 'string', ['string', 'number'])",
"wrap_compile.js")
} else {
c.compiler, err = c.ctx.RunScript("Module.cwrap('solidity_compile', 'string', ['string', 'number', 'number'])",
"wrap_compile.js")
}
return err
}
func (c *Compiler) Compile(input *Input) (*Output, error) {
fn, err := c.compiler.AsFunction()
if err != nil {
return nil, err
}
b, err := json.Marshal(input)
if err != nil {
return nil, err
}
c.mux.Lock()
defer c.mux.Unlock()
value, err := v8.NewValue(c.isolate, string(b))
if err != nil {
return nil, err
}
result, err := fn.Call(c.ctx.Global(), value)
if err != nil {
return nil, err
}
var output *Output
if err = json.Unmarshal([]byte(result.String()), &output); err != nil {
return nil, err
}
return output, nil
}
func (c *Compiler) Close() {
c.mux.Lock()
defer c.mux.Lock()
c.ctx.Close()
c.isolate.Dispose()
}