diff --git a/images/Makefile b/images/Makefile new file mode 100644 index 0000000..6a63adc --- /dev/null +++ b/images/Makefile @@ -0,0 +1,31 @@ +# Copyright 2017 . All rights reserved. +# Use of this source code is governed by a Apache +# license that can be found in the LICENSE file. + +UML_FILES=$(wildcard ./*.plantuml) +UML_SVG_FILES=$(patsubst %.plantuml,%.uml.svg,$(UML_FILES)) +UML_PNG_FILES=$(patsubst %.plantuml,%.uml.png,$(UML_FILES)) + +DOT_FILES=$(wildcard ./*.dot) +DOT_PNG_FILES=$(patsubst %.dot,%.dot.png,$(DOT_FILES)) + +default: $(UML_PNG_FILES) $(DOT_PNG_FILES) + @echo "ok" + +logo: + convert logo-2018-01.png -resize 300x65 logo.png + @echo "ok" + +clean: + -rm *.dot.png + -rm *.uml.png + -rm *.uml.svg + +%.uml.svg: %.plantuml + cat $< | docker run --rm -i chai2010/ibox:plantuml > $@ + +%.uml.png: %.plantuml + cat $< | docker run --rm -i chai2010/ibox:plantuml -tpng > $@ + +%.dot.png: %.dot + dot -Tpng -o $@ $< diff --git a/images/ch1-01-go-family-tree-x.dot.png b/images/ch1-01-go-family-tree-x.dot.png new file mode 100644 index 0000000..feb8adb Binary files /dev/null and b/images/ch1-01-go-family-tree-x.dot.png differ diff --git a/images/ch2-call-c-sum-v1.plantuml b/images/ch2-call-c-sum-v1.plantuml new file mode 100644 index 0000000..59a92d9 --- /dev/null +++ b/images/ch2-call-c-sum-v1.plantuml @@ -0,0 +1,46 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + +@startuml + +title C.sum(2, 3) + +|main.go| +:func main() { + C.sum(2, 3)) +}; + +|#AntiqueWhite|main.cgo1.go| +:func main() { + _Cfunc_sum(2, 3)) +}; + +|#AntiqueWhite|_cgo_types.go| +:func _Cfunc_sum(2, 3) double { + _cgo_runtime_cgocall(...) + return +}; + +|runtime.cgocall| +:_cgo_runtime_cgocall(...); + +fork + +|#AntiqueWhite|main.cgo2.c| +: double _cgo_xxx_Cfunc_sum(2, 3) { + return sum(2, 3) +}; + +|#AntiqueWhite|_cgo_export.c| +:sum(2, 3); + +endfork + +|runtime.cgocall| +:_cgo_runtime_cgocall(...); + +|main.go| +stop + +@enduml diff --git a/images/ch2-call-c-sum-v1.uml.png b/images/ch2-call-c-sum-v1.uml.png new file mode 100644 index 0000000..c4930ef Binary files /dev/null and b/images/ch2-call-c-sum-v1.uml.png differ diff --git a/images/ch2-call-c-sum-v2.plantuml b/images/ch2-call-c-sum-v2.plantuml new file mode 100644 index 0000000..9e1286b --- /dev/null +++ b/images/ch2-call-c-sum-v2.plantuml @@ -0,0 +1,63 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + +@startuml + +title c call go func + +|_testmain.c| +:int main() { + extern int sum(int a, int b) + sum(1, 2) + return 0 +}; +-[#green,dashed]-> + +fork + +|#AntiqueWhite|_cgo_export.c| +:int sum(int p0, int p1) { + struct { int p0, p1, r0; } a + _cgo_ctxt = _cgo_wait_runtime_init_done() + crosscall2(_cgoexp_xxx_sum, &a, 16, _cgo_ctxt) + _cgo_release_context(_cgo_ctxt) + return a.r0 +}; + +|runtime/cgo/*.asm| +:TEXT crosscall2(SB),NOSPLIT,$0; + +fork + +|#AntiqueWhite|_cgo_types.go| +:func _cgoexp_xxx_sum(a unsafe.Pointer, n int32, ctxt uintptr) { + fn := _cgoexpwrap_xxx_sum + _cgo_runtime_cgocallback( + _cgoexpwrap_xxx_sum, + ... + ) +}; + +|#AntiqueWhite|_cgo_types.go| +:func _cgoexpwrap_xxx_sum(p0, p1) r0 { + return sum(p0, p1) +}; + +|main.go| +://export sum +func sum(a, b C.int) C.int { + return a + b +}; + +endfork + +|runtime/cgo/*.asm| +:TEXT crosscall2(SB),NOSPLIT,$0; + +endfork + +|_testmain.c| +stop + +@enduml diff --git a/images/ch2-call-c-sum-v2.uml.png b/images/ch2-call-c-sum-v2.uml.png new file mode 100644 index 0000000..6c8bbc2 Binary files /dev/null and b/images/ch2-call-c-sum-v2.uml.png differ diff --git a/images/ch2-cgo-generated-files.dot b/images/ch2-cgo-generated-files.dot new file mode 100644 index 0000000..8b0da04 --- /dev/null +++ b/images/ch2-cgo-generated-files.dot @@ -0,0 +1,37 @@ +// Copyright 2018 . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +digraph G { + subgraph cluster_cgo_package_main { + label = "package main"; + + nocgo_x[label="nocgo_x.go", style=filled, color=gray]; + hello_go[label="hello.go", style=filled, color=orangered4]; + main_go[label="main.go", style=filled, color=darkgreen]; + nocgo_1[label="nocgo_1.go", style=filled, color=gray]; + } + + subgraph cluster_cgo_generated_files { + label = "cgo: generated fileds"; + + main_cgo2_c[label="main.cgo2.c", style=filled, color=green]; + main_cgo1_go[label="main.cgo1.go", style=filled, color=green]; + + hello_cgo2_c[label="hello.cgo2.c", style=filled, color=red]; + hello_cgo1_go[label="hello.cgo1.go", style=filled, color=red]; + + _cgo_gotypes_go[label="_cgo_gotypes.go", shape=box, style=filled, color=dodgerblue]; + _cgo_export_h[label="_cgo_export.h", shape=box, style=filled, color=dodgerblue]; + _cgo_export_c[label="_cgo_export.c", shape=box, style=filled, color=dodgerblue]; + + main_go -> main_cgo1_go -> _cgo_gotypes_go; + main_go -> main_cgo2_c -> _cgo_gotypes_go; + + hello_go -> hello_cgo1_go -> _cgo_gotypes_go; + hello_go -> hello_cgo2_c -> _cgo_gotypes_go; + + _cgo_gotypes_go -> _cgo_export_h; + _cgo_gotypes_go -> _cgo_export_c; + } +} diff --git a/images/ch2-cgo-generated-files.dot.png b/images/ch2-cgo-generated-files.dot.png new file mode 100644 index 0000000..dab55af Binary files /dev/null and b/images/ch2-cgo-generated-files.dot.png differ diff --git a/images/ch2-int32-to-char-ptr.plantuml b/images/ch2-int32-to-char-ptr.plantuml new file mode 100644 index 0000000..72d16e1 --- /dev/null +++ b/images/ch2-int32-to-char-ptr.plantuml @@ -0,0 +1,29 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + +@startuml + +title int32 <=> *C.char + +participant int32 +participant uintptr +participant unsafe.Pointer as unsafe_Pointer +participant "~*C.char" as c_char_ptr + +== Go == + +int32 -> uintptr: int32 to uintptr +uintptr -> unsafe_Pointer: uintptr to unsafe.Pointer + +== CGO == + +unsafe_Pointer -> c_char_ptr: unsafe.Pointer to *C.char +c_char_ptr -> unsafe_Pointer: ~*C.char to unsafe.Pointer + +== Go == + +unsafe_Pointer -> uintptr: unsafe.Pointer to uintptr +uintptr -> int32: uintptr to int32 + +@enduml diff --git a/images/ch2-int32-to-char-ptr.uml.png b/images/ch2-int32-to-char-ptr.uml.png new file mode 100644 index 0000000..4aa6190 Binary files /dev/null and b/images/ch2-int32-to-char-ptr.uml.png differ diff --git a/images/ch2-qsort-v2.plantuml b/images/ch2-qsort-v2.plantuml new file mode 100644 index 0000000..7516eae --- /dev/null +++ b/images/ch2-qsort-v2.plantuml @@ -0,0 +1,88 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + +@startuml + +title qsort + +participant go +participant c + +[--> go: qsort +activate go + +go -> go +activate go #DarkSalmon +note left + go_qsort_compare_info.elemsize = sv.Type().Elem().Size() + go_qsort_compare_info.fn = fn +end note + +deactivate go + +go -> c: C.qsort_proxy(cmp=go_qsort_compare) +activate c +note right +void qsort_proxy( + void* base, size_t num, size_t size, + int (*compare)(const void* a, const void* b) +) { + go_qsort_compare_save_base(base); + qsort(base, num, size, compare); +} +end note + +' begin + c -> c: C.go_qsort_compare_save_base + activate c #DarkSalmon + note right: callback go func + + go <- c: go_qsort_compare_save_base + activate go #DarkSalmon + note left + //export go_qsort_compare_save_base + func go_qsort_compare_save_base(base unsafe.Pointer) { + go_qsort_compare_info.base = uintptr(base) + } + var go_qsort_compare_info struct { + base uintptr + elemsize uintptr + fn func(a, b int) int + sync.RWMutex + } + end note + + go -> c: go_qsort_compare_save_base done + deactivate go + + deactivate c +' end + +loop + c -> c: C.go_qsort_compare + activate c #DarkSalmon + note right: callback go func + + c -> go: go_qsort_compare + activate go #DarkSalmon + note left + //export go_qsort_compare_save_base + func go_qsort_compare_save_base(base unsafe.Pointer) { + go_qsort_compare_info.base = uintptr(base) + } + end note + + go -> c: go_qsort_compare done + deactivate go + + deactivate c +end + +go <- c: C.qsort_proxy done +deactivate c + +[<-- go: done +deactivate go + +@enduml diff --git a/images/ch2-qsort-v2.uml.png b/images/ch2-qsort-v2.uml.png new file mode 100644 index 0000000..a197397 Binary files /dev/null and b/images/ch2-qsort-v2.uml.png differ diff --git a/images/ch2-x-ptr-to-y-ptr.plantuml b/images/ch2-x-ptr-to-y-ptr.plantuml new file mode 100644 index 0000000..7333271 --- /dev/null +++ b/images/ch2-x-ptr-to-y-ptr.plantuml @@ -0,0 +1,23 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + +@startuml + +title *X <=> *Y + +participant "~*X" as x_ptr +participant unsafe.Pointer as unsafe_Pointer +participant "~*Y" as y_ptr + +== *X => *Y == + +x_ptr -> unsafe_Pointer: ~*X to unsafe.Pointer +unsafe_Pointer -> y_ptr: unsafe.Pointer to *Y + +== *Y => *X == + +y_ptr -> unsafe_Pointer: ~*Y to unsafe.Pointer +unsafe_Pointer -> x_ptr: unsafe.Pointer to *X + +@enduml diff --git a/images/ch2-x-ptr-to-y-ptr.uml.png b/images/ch2-x-ptr-to-y-ptr.uml.png new file mode 100644 index 0000000..574ece5 Binary files /dev/null and b/images/ch2-x-ptr-to-y-ptr.uml.png differ diff --git a/images/ch2-x-slice-to-y-slice.plantuml b/images/ch2-x-slice-to-y-slice.plantuml new file mode 100644 index 0000000..66cee0a --- /dev/null +++ b/images/ch2-x-slice-to-y-slice.plantuml @@ -0,0 +1,36 @@ +' Copyright 2017 . All rights reserved. +' Use of this source code is governed by a Apache +' license that can be found in the LICENSE file. + + +'var p []X +'var q []Y // q = p + +'pHdr := (*reflect.SliceHeader)(unsafe.Pointer(&p)) +'qHdr := (*reflect.SliceHeader)(unsafe.Pointer(&q)) + +'pHdr.Data = qHdr.Data +'pHdr.Len = qHdr.Len * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0]) +'pHdr.Cap = qHdr.Cap * unsafe.Sizeof(q[0]) / unsafe.Sizeof(p[0]) + + +@startuml + +title []X <=> []Y + +participant "var x []X\nvar y []Y" as slice +participant "var px *SliceHeader\nvar py *SliceHeader" as slice_header + +== []X and []Y to *reflect.SliceHeader == + +slice -> slice_header: px := (*reflect.SliceHeader)(unsafe.Pointer(&x))\npy := (*reflect.SliceHeader)(unsafe.Pointer(&y)) + +== copy *px to *py == + +slice_header -> slice_header: ~*py = *px + +== y changed by *py == + +slice -> slice: y = x + +@enduml diff --git a/images/ch2-x-slice-to-y-slice.uml.png b/images/ch2-x-slice-to-y-slice.uml.png new file mode 100644 index 0000000..9b6ad2b Binary files /dev/null and b/images/ch2-x-slice-to-y-slice.uml.png differ