Skip to content
Merged
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
2 changes: 2 additions & 0 deletions compiler/compiler.go
Original file line number Diff line number Diff line change
Expand Up @@ -1686,6 +1686,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
b.createRuntimeInvoke("_panic", argValues, "")
return llvm.Value{}, nil
case "print", "println":
b.createRuntimeCall("printlock", nil, "")
for i, value := range argValues {
if i >= 1 && callName == "println" {
b.createRuntimeCall("printspace", nil, "")
Expand Down Expand Up @@ -1746,6 +1747,7 @@ func (b *builder) createBuiltin(argTypes []types.Type, argValues []llvm.Value, c
if callName == "println" {
b.createRuntimeCall("printnl", nil, "")
}
b.createRuntimeCall("printunlock", nil, "")
return llvm.Value{}, nil // print() or println() returns void
case "real":
cplx := argValues[0]
Expand Down
10 changes: 10 additions & 0 deletions compiler/testdata/defer-cortex-m-qemu.ll
Original file line number Diff line number Diff line change
Expand Up @@ -122,12 +122,18 @@ declare void @runtime.destroyDeferFrame(ptr dereferenceable_or_null(24), ptr) #2
; Function Attrs: nounwind
define internal void @"main.deferSimple$1"(ptr %context) unnamed_addr #1 {
entry:
call void @runtime.printlock(ptr undef) #4
call void @runtime.printint32(i32 3, ptr undef) #4
call void @runtime.printunlock(ptr undef) #4
ret void
}

declare void @runtime.printlock(ptr) #2

declare void @runtime.printint32(i32, ptr) #2

declare void @runtime.printunlock(ptr) #2

; Function Attrs: nounwind
define hidden void @main.deferMultiple(ptr %context) unnamed_addr #1 {
entry:
Expand Down Expand Up @@ -250,14 +256,18 @@ rundefers.end7: ; preds = %rundefers.loophead1
; Function Attrs: nounwind
define internal void @"main.deferMultiple$1"(ptr %context) unnamed_addr #1 {
entry:
call void @runtime.printlock(ptr undef) #4
call void @runtime.printint32(i32 3, ptr undef) #4
call void @runtime.printunlock(ptr undef) #4
ret void
}

; Function Attrs: nounwind
define internal void @"main.deferMultiple$2"(ptr %context) unnamed_addr #1 {
entry:
call void @runtime.printlock(ptr undef) #4
call void @runtime.printint32(i32 5, ptr undef) #4
call void @runtime.printunlock(ptr undef) #4
ret void
}

Expand Down
6 changes: 6 additions & 0 deletions compiler/testdata/goroutine-cortex-m-qemu-tasks.ll
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ entry:
%stacksize = call i32 @"internal/task.getGoroutineStackSize"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr undef) #9
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 %stacksize, ptr undef) #9
%2 = load i32, ptr %n, align 4
call void @runtime.printlock(ptr undef) #9
call void @runtime.printint32(i32 %2, ptr undef) #9
call void @runtime.printunlock(ptr undef) #9
ret void
}

Expand All @@ -91,8 +93,12 @@ entry:
ret void
}

declare void @runtime.printlock(ptr) #2

declare void @runtime.printint32(i32, ptr) #2

declare void @runtime.printunlock(ptr) #2

; Function Attrs: nounwind
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #1 {
entry:
Expand Down
6 changes: 6 additions & 0 deletions compiler/testdata/goroutine-wasm-asyncify.ll
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ entry:
store ptr %n, ptr %1, align 4
call void @"internal/task.start"(i32 ptrtoint (ptr @"main.closureFunctionGoroutine$1$gowrapper" to i32), ptr nonnull %0, i32 65536, ptr undef) #9
%2 = load i32, ptr %n, align 4
call void @runtime.printlock(ptr undef) #9
call void @runtime.printint32(i32 %2, ptr undef) #9
call void @runtime.printunlock(ptr undef) #9
ret void
}

Expand All @@ -98,8 +100,12 @@ entry:
unreachable
}

declare void @runtime.printlock(ptr) #1

declare void @runtime.printint32(i32, ptr) #1

declare void @runtime.printunlock(ptr) #1

; Function Attrs: nounwind
define hidden void @main.funcGoroutine(ptr %fn.context, ptr %fn.funcptr, ptr %context) unnamed_addr #2 {
entry:
Expand Down
78 changes: 54 additions & 24 deletions src/runtime/print.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
package runtime

import (
"internal/task"
"unsafe"
)

type stringer interface {
String() string
}

// Lock to make sure print calls do not interleave.
// This is a no-op lock on systems that do not have parallelism.
var printLock task.PMutex

func printlock() {
printLock.Lock()
}

func printunlock() {
printLock.Unlock()
}

//go:nobounds
func printstring(s string) {
for i := 0; i < len(s); i++ {
Expand Down Expand Up @@ -293,67 +306,84 @@ func printnl() {
func printitf(msg interface{}) {
switch msg := msg.(type) {
case bool:
print(msg)
printbool(msg)
case int:
print(msg)
switch unsafe.Sizeof(msg) {
case 8:
printint64(int64(msg))
case 4:
printint32(int32(msg))
}
case int8:
print(msg)
printint8(msg)
case int16:
print(msg)
printint16(msg)
case int32:
print(msg)
printint32(msg)
case int64:
print(msg)
printint64(msg)
case uint:
print(msg)
switch unsafe.Sizeof(msg) {
case 8:
printuint64(uint64(msg))
case 4:
printuint32(uint32(msg))
}
case uint8:
print(msg)
printuint8(msg)
case uint16:
print(msg)
printuint16(msg)
case uint32:
print(msg)
printuint32(msg)
case uint64:
print(msg)
printuint64(msg)
case uintptr:
print(msg)
printuintptr(msg)
case float32:
print(msg)
printfloat32(msg)
case float64:
print(msg)
printfloat64(msg)
case complex64:
print(msg)
printcomplex64(msg)
case complex128:
print(msg)
printcomplex128(msg)
case string:
print(msg)
printstring(msg)
case error:
print(msg.Error())
printstring(msg.Error())
case stringer:
print(msg.String())
printstring(msg.String())
default:
// cast to underlying type
itf := *(*_interface)(unsafe.Pointer(&msg))
putchar('(')
printuintptr(uintptr(itf.typecode))
putchar(':')
print(itf.value)
printptr(uintptr(itf.value))
putchar(')')
}
}

func printmap(m *hashmap) {
print("map[")
printstring("map[")
if m == nil {
print("nil")
printstring("nil")
} else {
print(uint(m.count))
switch unsafe.Sizeof(m.count) {
case 8:
printuint64(uint64(m.count))
case 4:
printuint32(uint32(m.count))
case 2:
printuint16(uint16(m.count))
}
}
putchar(']')
}

func printptr(ptr uintptr) {
if ptr == 0 {
print("nil")
printstring("nil")
return
}
putchar('0')
Expand Down
6 changes: 6 additions & 0 deletions testdata/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ func main() {

// print interface
println(interface{}(nil))
println(interface{}(true))
println(interface{}("foobar"))
println(interface{}(int64(-3)))
println(interface{}(uint64(3)))
println(interface{}(int(-3)))
println(interface{}(uint(3)))

// print map
println(map[string]int{"three": 3, "five": 5})
Expand Down
6 changes: 6 additions & 0 deletions testdata/print.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ a b c
+3.140000e+000
(+5.000000e+000+1.234500e+000i)
(0:nil)
true
foobar
-3
3
-3
3
map[2]
true false
[0/0]nil
Expand Down