diff --git a/_examples/llvm/build.sh b/_examples/llvm/build.sh new file mode 100755 index 0000000000000000000000000000000000000000..7b37995e162d0f6675169c204faff4277e79bfd5 --- /dev/null +++ b/_examples/llvm/build.sh @@ -0,0 +1,35 @@ +#! /bin/bash + +wa native --target=avr arduino_blink.wa +wa native array_0.wa +wa native array_1.wa +wa native array_2.wa +wa native bitwise_logic.wa +wa native compare.wa +wa native convert_0.wa +wa native convert_1.wa +wa native convert_2.wa +wa native convert_3.wa +wa native float32.wa +wa native global_constant.wa +wa native global_variable_0.wa +wa native global_variable_1.wa +wa native heart.wa +wa native internal_function.wa +wa native loop_0.wa +wa native loop_1.wa +wa native multi_ret.wa +wa native pointer.wa +wa native prime.wa +wa native print_0.wa +wa native print_1.wa +wa native print_2.wa +wa native print_3.wa +wa native shift.wa +wa native struct_0.wa +wa native struct_1.wa +wa native struct_2.wa +wa native struct_3.wa +wa native unconditional_jump.wa + +rm -f *.ll *.s diff --git a/_examples/llvm/internal_function.wa b/_examples/llvm/internal_function.wa new file mode 100644 index 0000000000000000000000000000000000000000..d9e80e216c41d44848b0b4d6ad3793f8da19c01c --- /dev/null +++ b/_examples/llvm/internal_function.wa @@ -0,0 +1,18 @@ +# Test the llvm backend. +# Test anonymous functions and closure functions. + +fn main() { + print("Hello, ") + fn() { + println("World!") + }() + + var i: int + show := fn() { + println("i = ", i) + } + + for i = 0; i < 10; i++ { + show() + } +} diff --git a/internal/app/opt.go b/internal/app/opt.go index e9806f9a84a5061cda491f2afcf3413afcdf47cb..5f856976cafd9de11b70b277622541db3bc8143a 100644 --- a/internal/app/opt.go +++ b/internal/app/opt.go @@ -44,6 +44,9 @@ func (opt *Option) Config() *config.Config { case "arm64": cfg.WaSizes.MaxAlign = 8 cfg.WaSizes.WordSize = 8 + case "native": + cfg.WaSizes.MaxAlign = 8 + cfg.WaSizes.WordSize = 8 default: panic("todo") } diff --git a/internal/backends/compiler_llvm/compile.go b/internal/backends/compiler_llvm/compile.go index 099aa1eba353a4225b585746070f495a35d9ba1b..3fb3c7744202ee1ca986c851ee0ff27e9bec113d 100644 --- a/internal/backends/compiler_llvm/compile.go +++ b/internal/backends/compiler_llvm/compile.go @@ -21,6 +21,7 @@ type Compiler struct { output strings.Builder debug bool fmts []FmtStr + anofn []*ssa.Function } func New(target string, debug bool) *Compiler { @@ -142,6 +143,14 @@ func (p *Compiler) compilePackage(pkg *ssa.Package) error { } } + // Generate LLVM-IR for each internal function. + for _, v := range p.anofn { + if err := p.compileFunction(v); err != nil { + return err + } + } + p.anofn = []*ssa.Function{} + return nil } diff --git a/internal/backends/compiler_llvm/compile_value.go b/internal/backends/compiler_llvm/compile_value.go index 25c2479f08d49f4ca32152b1e360a0a7be832dd5..36f20ec857518d86a578e85046fcc3c75adbc170 100644 --- a/internal/backends/compiler_llvm/compile_value.go +++ b/internal/backends/compiler_llvm/compile_value.go @@ -387,6 +387,10 @@ func (p *Compiler) compileCall(val *ssa.Call) error { // Emit the function name. p.output.WriteString(" @") callee := val.Call.StaticCallee() + // This callee is an internal function, whose body will be genereated later. + if callee.Parent() != nil { + p.anofn = append(p.anofn, callee) + } if len(callee.LinkName()) > 0 { p.output.WriteString(callee.LinkName()) } else { diff --git a/main.go b/main.go index bba24c43359e7d9b24e1c1e58a7cceb6ab99df69..dcde85e750469b31dcb1f43c1460353b6f4b0f13 100644 --- a/main.go +++ b/main.go @@ -304,7 +304,7 @@ func main() { } infile = c.Args().First() - ctx := app.NewApp(build_Options(c)) + ctx := app.NewApp(build_Options(c, true)) if err := ctx.LLVM(infile, outfile, target, debug); err != nil { fmt.Println(err) os.Exit(1) @@ -472,6 +472,7 @@ func build_Options(c *cli.Context, isLLVMBackend ...bool) *app.Option { opt.TargetArch = "wasm" if len(isLLVMBackend) > 0 && isLLVMBackend[0] { opt.TargetArch = "native" + return opt } switch c.String("target") { case "wa", config.WaOS_Walang: