提交 b1740a4a 编写于 作者: 3 3dgen

增加导入函数

上级 e17384d0
......@@ -4,6 +4,7 @@ package compiler_wasm
import (
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir"
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
"github.com/wa-lang/wa/internal/loader"
"github.com/wa-lang/wa/internal/ssa"
)
......@@ -11,7 +12,7 @@ import (
type Compiler struct {
ssaPkg *ssa.Package
module *wir.Module
module wir.Module
}
func New() *Compiler {
......@@ -34,6 +35,13 @@ func (p *Compiler) CompilePackage(ssaPkg *ssa.Package) {
var gs []*ssa.Global
var fns []*ssa.Function
{
var sig wir.FuncSig
sig.Params = append(sig.Params, wtypes.Int32{})
p.module.Imports = append(p.module.Imports, wir.NewImpFunc("js", "print_i32", "$$print_i32", sig))
p.module.Imports = append(p.module.Imports, wir.NewImpFunc("js", "print_char", "$$print_char", sig))
}
for _, m := range p.ssaPkg.Members {
switch member := m.(type) {
case *ssa.Type:
......@@ -76,9 +84,10 @@ func (p *Compiler) CompilePackage(ssaPkg *ssa.Package) {
}
}
for _, v := range fns {
newFunctionGenerator(p).genFunction(v)
p.module.Funcs = append(p.module.Funcs, newFunctionGenerator(p).genFunction(v))
}
println(p.module.String())
}
func (p *Compiler) String() string {
......
......@@ -29,7 +29,7 @@ type functionGenerator struct {
}
func newFunctionGenerator(p *Compiler) *functionGenerator {
return &functionGenerator{module: p.module, locals_map: make(map[ssa.Value]wir.Value)}
return &functionGenerator{module: &p.module, locals_map: make(map[ssa.Value]wir.Value)}
}
func (g *functionGenerator) getValue(i ssa.Value) wir.Value {
......@@ -151,7 +151,6 @@ func (g *functionGenerator) genFunction(f *ssa.Function) *wir.Function {
wir_fn.Insts = append(wir_fn.Insts, block_temp)
wir_fn.Locals = g.registers
println(wir_fn.Format(" "))
return &wir_fn
}
......
// 版权 @2021 凹语言 作者。保留所有权利。
package compiler_wasm
import (
"bytes"
"github.com/wa-lang/wa/internal/3rdparty/wasm/encoding"
"github.com/wa-lang/wa/internal/3rdparty/wasm/instruction"
"github.com/wa-lang/wa/internal/3rdparty/wasm/module"
"github.com/wa-lang/wa/internal/3rdparty/wasm/types"
"github.com/wa-lang/wa/internal/ast"
"github.com/wa-lang/wa/internal/loader"
)
type Compiler struct {
stages []func() error
prog *loader.Program
globalNames []string
globalNodes map[string]*ast.Ident
module *module.Module
mainBody *module.CodeEntry
tinyMainIndex uint32
tinyReadIndex uint32
tinyWriteIndex uint32
}
func New() *Compiler {
p := new(Compiler)
p.stages = []func() error{
p.reset,
p.initModule,
p.emitGlobals,
p.emitMainBody,
}
return p
}
func (p *Compiler) Compile(prog *loader.Program) (output string, err error) {
p.prog = prog
for _, stage := range p.stages {
if err := stage(); err != nil {
return "", err
}
}
var buf bytes.Buffer
if err := encoding.WriteModule(&buf, p.module); err != nil {
return "", err
}
return buf.String(), nil
}
func (p *Compiler) reset() error {
p.globalNames = []string{}
p.globalNodes = make(map[string]*ast.Ident)
return nil
}
func (p *Compiler) initModule() error {
p.module = &module.Module{
Names: module.NameSection{
Module: "walang",
},
Memory: module.MemorySection{
Memorys: []module.Memory{
{InitPages: 1, MaxPages: 1},
},
},
Export: module.ExportSection{
Exports: []module.Export{
{
Name: "memory",
Descriptor: module.ExportDescriptor{
Type: module.MemoryExportType,
Index: 0,
},
},
},
},
}
// init types
p.tinyReadIndex = 0
p.tinyWriteIndex = 1
p.tinyMainIndex = 2
p.module.Type.Functions = []module.FunctionType{
// func __tiny_read() int32
{Results: []types.ValueType{types.I32}},
// func __tiny_write(x int32)
{Params: []types.ValueType{types.I32}},
// func _start
{},
}
// import
p.module.Import.Imports = []module.Import{
{
Module: "env",
Name: "__tiny_read",
Descriptor: module.FunctionImport{
Func: p.tinyReadIndex,
},
},
{
Module: "env",
Name: "__tiny_write",
Descriptor: module.FunctionImport{
Func: p.tinyWriteIndex,
},
},
}
// _start func
p.module.Function.TypeIndices = []uint32{
p.tinyMainIndex,
}
p.module.Names.Functions = append(p.module.Names.Functions, module.NameMap{
Index: p.tinyMainIndex,
Name: "_start",
})
// _start func body
{
var entry = &module.CodeEntry{
Func: module.Function{
Locals: []module.LocalDeclaration{},
Expr: module.Expr{
Instrs: []instruction.Instruction{
instruction.I32Const{Value: 42},
instruction.Call{Index: p.tinyWriteIndex},
instruction.Return{},
},
},
},
}
var buf bytes.Buffer
if err := encoding.WriteCodeEntry(&buf, entry); err != nil {
return err
}
p.module.Code.Segments = append(p.module.Code.Segments, module.RawCodeSegment{
Code: buf.Bytes(),
})
}
// export _start
p.module.Export.Exports = append(p.module.Export.Exports, module.Export{
Name: "_start",
Descriptor: module.ExportDescriptor{
Type: module.FunctionExportType,
Index: p.tinyMainIndex,
},
})
return nil
}
func (p *Compiler) emitGlobals() error {
if len(p.module.Global.Globals) > 0 {
return nil
}
panic("TODO: support WASM")
}
func (p *Compiler) emitMainBody() error {
p.mainBody = &module.CodeEntry{
Func: module.Function{
Locals: []module.LocalDeclaration{},
Expr: module.Expr{
Instrs: []instruction.Instruction{
// instruction.I32Const{Value: 42 + 1},
// instruction.Call{Index: p.tinyWriteIndex},
},
},
},
}
if err := p.compileNone(&p.mainBody.Func.Expr, nil); err != nil {
return err
}
var buf bytes.Buffer
if err := encoding.WriteCodeEntry(&buf, p.mainBody); err != nil {
return err
}
// replace main body
p.module.Code.Segments = []module.RawCodeSegment{
{Code: buf.Bytes()},
}
return nil
}
func (p *Compiler) compileNone(ctx *module.Expr, node ast.Node) error {
if node == nil {
return nil
}
panic("TODO: support WASM")
}
func (p *Compiler) globalIndexByName(name string) uint32 {
for i, s := range p.globalNames {
if s == name {
return uint32(i) + 1
}
}
return 0
}
func (p *Compiler) emit(ctx *module.Expr, x ...instruction.Instruction) {
ctx.Instrs = append(ctx.Instrs, x...)
}
......@@ -35,6 +35,24 @@ func (f *Function) Format(indent string) string {
s += inst.Format(indent+" ") + "\n"
}
s += indent + ") ;;" + f.Name + "\n"
s += indent + ") ;;" + f.Name
return s
}
func (sig *FuncSig) String() string {
str := ""
for _, param := range sig.Params {
rps := param.Raw()
for _, rp := range rps {
str += " (param " + rp.Name() + ")"
}
}
for _, ret := range sig.Results {
rrs := ret.Raw()
for _, rp := range rrs {
str += " (result " + rp.Name() + ")"
}
}
return str
}
package wir
/**************************************
ImpObj:
**************************************/
type ImpObj struct {
moduleName string
objName string
}
func (o *ImpObj) ModuleName() string { return o.moduleName }
func (o *ImpObj) ObjName() string { return o.objName }
/**************************************
ImpFunc:
**************************************/
type ImpFunc struct {
ImpObj
funcName string
sig FuncSig
}
func NewImpFunc(moduleName string, objName string, funcName string, sig FuncSig) *ImpFunc {
return &ImpFunc{ImpObj: ImpObj{moduleName: moduleName, objName: objName}, funcName: funcName, sig: sig}
}
func (o *ImpFunc) Type() ObjType { return ObjTypeFunc }
func (o *ImpFunc) Format(indent string) string {
return "(import \"" + o.moduleName + "\" \"" + o.objName + "\" (func " + o.funcName + o.sig.String() + "))"
}
package wir
func (m *Module) String() string {
s := "(module\n"
for _, i := range m.Imports {
s += i.Format(" ") + "\n"
}
for _, f := range m.Funcs {
s += f.Format(" ") + "\n"
}
s += ") ;;module"
return s
}
package wir
import "github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
import (
"github.com/wa-lang/wa/internal/backends/compiler_wasm/wir/wtypes"
)
type Module struct {
Funcs []Function
Imports []Import
Funcs []*Function
}
/**************************************
Import:
**************************************/
type Import interface {
Format(indent string) string
ModuleName() string
ObjName() string
Type() ObjType
}
/**************************************
......@@ -18,6 +31,14 @@ type Function struct {
Insts []Instruction
}
/**************************************
FuncSig:
**************************************/
type FuncSig struct {
Params []wtypes.ValueType
Results []wtypes.ValueType
}
/**************************************
Instruction:
**************************************/
......@@ -44,6 +65,9 @@ type Value interface {
Raw() []Value
}
/**************************************
OpCode:
**************************************/
type OpCode int32
const (
......@@ -59,3 +83,15 @@ const (
OpCodeLe
OpCodeGe
)
/**************************************
ObjType:
**************************************/
type ObjType int32
const (
ObjTypeFunc ObjType = iota
ObjTypeMem
ObjTypeTable
ObjTypeGlobal
)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册