From 0b3676c498f62665a8861d5d9eea2b16f9d91e62 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 12 Oct 2017 16:31:14 +0100 Subject: [PATCH 1/2] syscall_unix: fallback to process.exit when available "go test" currently always fails with "fatal error: all goroutines are asleep - deadlock!". In fact, all programs that use "os.Exit" will fail with this. It turns out that the current "runtime.Goexit" function throws an exception which propagates up which violates the expected behavior of the exit syscall (which should not return). Therefore call "process.exit" when available. Fixes #626 --- compiler/natives/src/syscall/syscall_unix.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/natives/src/syscall/syscall_unix.go b/compiler/natives/src/syscall/syscall_unix.go index cd2c58913..358b1d1a0 100644 --- a/compiler/natives/src/syscall/syscall_unix.go +++ b/compiler/natives/src/syscall/syscall_unix.go @@ -67,6 +67,9 @@ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { return uintptr(array.Length()), 0, 0 } if trap == SYS_EXIT { + if process := js.Global.Get("process"); process != js.Undefined { + process.Call("exit", a1) + } runtime.Goexit() } printWarning() From 3416b8f87b924cb9f57f1af4cabf9994441166ed Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Fri, 13 Oct 2017 14:08:07 +0100 Subject: [PATCH 2/2] syscall_unix: use process.stdout/process.stderr for SYS_WRITE printToConsole does some internal line buffering (not even involving the stdio layer) which is only flushed on normal exit via $flushConsole. When using process.exit, this is not called though. Therefore avoid the internal buffering, and use Node's stdio directly. --- compiler/natives/src/syscall/syscall_unix.go | 21 +++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/natives/src/syscall/syscall_unix.go b/compiler/natives/src/syscall/syscall_unix.go index 358b1d1a0..dc9590e1c 100644 --- a/compiler/natives/src/syscall/syscall_unix.go +++ b/compiler/natives/src/syscall/syscall_unix.go @@ -61,9 +61,24 @@ func Syscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) { } if trap == SYS_WRITE && (a1 == 1 || a1 == 2) { array := js.InternalObject(a2) - slice := make([]byte, array.Length()) - js.InternalObject(slice).Set("$array", array) - printToConsole(slice) + if process := js.Global.Get("process"); process != js.Undefined { + var buffer interface{} + if bufferFrom := js.Global.Get("Buffer").Get("from"); bufferFrom != js.Undefined { + // since node 5.10.0 + buffer = bufferFrom.Invoke(array) + } else { + buffer = js.Global.Get("Buffer").New(array) + } + if a1 == 1 { + process.Get("stdout").Call("write", buffer) + } else { + process.Get("stderr").Call("write", buffer) + } + } else { + slice := make([]byte, array.Length()) + js.InternalObject(slice).Set("$array", array) + printToConsole(slice) + } return uintptr(array.Length()), 0, 0 } if trap == SYS_EXIT {