diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 4e72f5a0..1e413d9c 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -2,9 +2,11 @@ #include "runtime.h" #include +void go_init() __asm__("runtime.initAll"); void go_main() __asm__("main.main"); int main() { + go_init(); go_main(); return 0; diff --git a/src/runtime/runtime_nrf.c b/src/runtime/runtime_nrf.c index ea314034..2271bf25 100644 --- a/src/runtime/runtime_nrf.c +++ b/src/runtime/runtime_nrf.c @@ -18,7 +18,6 @@ void uart_send(uint8_t c) { } void _start() { - uart_init(6); // pin_tx = 6, for NRF52840-DK main(); } diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index 93d96611..447ad28d 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -6,6 +6,10 @@ package runtime // #include "runtime_nrf.h" import "C" +func init() { + C.uart_init(6) // pin_tx = 6, for NRF52840-DK +} + const Microsecond = 1 func putchar(c byte) { diff --git a/tgo.go b/tgo.go index ea4a27df..a8682128 100644 --- a/tgo.go +++ b/tgo.go @@ -55,6 +55,7 @@ type Compiler struct { memsetIntrinsic llvm.Value itfTypeNumbers map[types.Type]uint64 itfTypes []types.Type + initFuncs []llvm.Value } type Frame struct { @@ -212,6 +213,17 @@ func (c *Compiler) Parse(mainPath string, buildTags []string) error { c.parsePackage(program, pkg) } + // After all packages are imported, add a synthetic initializer function + // that calls the initializer of each package. + initType := llvm.FunctionType(llvm.VoidType(), nil, false) + initFn := llvm.AddFunction(c.mod, "runtime.initAll", initType) + block := c.ctx.AddBasicBlock(initFn, "entry") + c.builder.SetInsertPointAtEnd(block) + for _, fn := range c.initFuncs { + c.builder.CreateCall(fn, nil, "") + } + c.builder.CreateRetVoid() + return nil } @@ -434,7 +446,7 @@ func (c *Compiler) parseFuncDecl(f *ssa.Function) (*Frame, error) { } func (c *Compiler) parseFunc(frame *Frame, f *ssa.Function) error { - if frame.llvmFn.Name() != "main.main" { + if frame.llvmFn.Name() != "main.main" && frame.llvmFn.Name() != "runtime.init" { // This function is only used from within Go. frame.llvmFn.SetLinkage(llvm.PrivateLinkage) }