Skip to content

Add support for using wizer to handle running initAll() #3655

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -1051,9 +1051,10 @@ func createEmbedObjectFile(data, hexSum, sourceFile, sourceDir, tmpdir string, c
// needed to convert a program to its final form. Some transformations are not
// optional and must be run as the compiler expects them to run.
func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues map[string]map[string]string) error {
err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA())
if err != nil {
return err
if config.Options.InterpTimeout != 0 {
if err := interp.Run(mod, config.Options.InterpTimeout, config.DumpSSA()); err != nil {
return err
}
}
if config.VerifyIR() {
// Only verify if we really need it.
Expand All @@ -1069,7 +1070,7 @@ func optimizeProgram(mod llvm.Module, config *compileopts.Config, globalValues m
}

// Insert values from -ldflags="-X ..." into the IR.
err = setGlobalValues(mod, globalValues)
err := setGlobalValues(mod, globalValues)
if err != nil {
return err
}
Expand Down
6 changes: 6 additions & 0 deletions src/runtime/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ const Compiler = "tinygo"
// package.
func initAll()

var runtimeInitialized = false

func runtime_is_initialized() bool {
return runtimeInitialized
}

//go:linkname callMain main.main
func callMain()

Expand Down
36 changes: 34 additions & 2 deletions src/runtime/runtime_wasip1.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,28 @@ func __wasm_call_ctors()

//export _start
func _start() {
runtimeInitialize()
run()
}

//export runtime.initialize
func runtimeInitialize() {
if runtimeInitialized {
// Second time initialization is happening. Refresh environment
// to whatever our current host gives us instead of whatever
// libc cached.
reset_libc_environment()
return
}
// These need to be initialized early so that the heap can be initialized.
heapStart = uintptr(unsafe.Pointer(&heapStartSymbol))
heapEnd = uintptr(wasm_memory_size(0) * wasmPageSize)
run()
initHeap()
initAll()
if hasScheduler {
go func() {}()
}
runtimeInitialized = true
}

// Read the command line arguments from WASI.
Expand All @@ -29,6 +47,17 @@ func init() {
__wasm_call_ctors()
}

//export __wasilibc_deinitialize_environ
func __wasilibc_deinitialize_environ()

//export __wasilibc_initialize_environ
func __wasilibc_initialize_environ()

func reset_libc_environment() {
__wasilibc_deinitialize_environ()
__wasilibc_initialize_environ()
}

var args []string

//go:linkname os_runtime_args os.runtime_args
Expand All @@ -39,7 +68,10 @@ func os_runtime_args() []string {
var argc, argv_buf_size uint32
args_sizes_get(&argc, &argv_buf_size)
if argc == 0 {
return nil
// Most things expect os.Args to have at least the
// program name. We don't have one, but also don't
// return just a nil slice.
return []string{""}
}

// Obtain the command line arguments
Expand Down
9 changes: 7 additions & 2 deletions src/runtime/scheduler_any.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ func sleep(duration int64) {
// run is called by the program entry point to execute the go program.
// With a scheduler, init and the main function are invoked in a goroutine before starting the scheduler.
func run() {
initHeap()
if !runtimeInitialized {
initHeap()
}
go func() {
initAll()
if !runtimeInitialized {
initAll()
runtimeInitialized = true
}
callMain()
schedulerDone = true
}()
Expand Down
7 changes: 5 additions & 2 deletions src/runtime/scheduler_none.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ func getSystemStackPointer() uintptr {
// run is called by the program entry point to execute the go program.
// With the "none" scheduler, init and the main function are invoked directly.
func run() {
initHeap()
initAll()
if !runtimeInitialized {
initHeap()
initAll()
runtimeInitialized = true
}
callMain()
}

Expand Down
7 changes: 7 additions & 0 deletions src/syscall/build_asserts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build syscall_asserts

package syscall

// enable assertions for checking Environ during runtime preinitialization.
// This is to catch people using os.Environ() during package inits with wizer.
const panicOnEnvironDuringInitAll = true
7 changes: 7 additions & 0 deletions src/syscall/build_noasserts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build !syscall_asserts

package syscall

// enable assertions for checking Environ during runtime preinitialization.
// This is to catch people using os.Environ() during package init with wizer.
const panicOnEnvironDuringInitAll = false
6 changes: 6 additions & 0 deletions src/syscall/syscall_libc.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,13 @@ func Mprotect(b []byte, prot int) (err error) {
return
}

//go:linkname runtime_is_initialized runtime.runtime_is_initialized
func runtime_is_initialized() bool

func Environ() []string {
if panicOnEnvironDuringInitAll && !runtime_is_initialized() {
panic("syscall.Environ() called during runtime preinitialization")
}

// This function combines all the environment into a single allocation.
// While this optimizes for memory usage and garbage collector
Expand Down
Loading