From 2fdc98fa002219f28f5b95c7917a692304ff73d8 Mon Sep 17 00:00:00 2001 From: chai2010 Date: Thu, 27 Dec 2018 07:48:22 +0800 Subject: [PATCH] =?UTF-8?q?ch3.6:=20=E5=A2=9E=E5=8A=A0=E9=97=AD=E5=8C=85?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=9A=84=E4=BE=8B=E5=AD=90=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/ch3.6/closure/main.go | 34 +++++++++++++++++++++++++++++ examples/ch3.6/closure/main_amd64.s | 22 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 examples/ch3.6/closure/main.go create mode 100644 examples/ch3.6/closure/main_amd64.s diff --git a/examples/ch3.6/closure/main.go b/examples/ch3.6/closure/main.go new file mode 100644 index 0000000..d299542 --- /dev/null +++ b/examples/ch3.6/closure/main.go @@ -0,0 +1,34 @@ +// Copyright © 2018 ChaiShushan . +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ + +package main + +import ( + "unsafe" +) + +type FunTwiceClosure struct { + F uintptr + X int +} + +func NewTwiceFunClosure(x int) func() int { + var p = &FunTwiceClosure{ + F: asmFunTwiceClosureAddr(), + X: x, + } + return ptrToFunc(unsafe.Pointer(p)) +} + +func ptrToFunc(p unsafe.Pointer) func() int + +func asmFunTwiceClosureAddr() uintptr +func asmFunTwiceClosureBody() + +func main() { + fnTwice := NewTwiceFunClosure(1) + + println(fnTwice()) // 1*2 => 2 + println(fnTwice()) // 2*2 => 4 + println(fnTwice()) // 4*2 => 8 +} diff --git a/examples/ch3.6/closure/main_amd64.s b/examples/ch3.6/closure/main_amd64.s new file mode 100644 index 0000000..630dce1 --- /dev/null +++ b/examples/ch3.6/closure/main_amd64.s @@ -0,0 +1,22 @@ +// Copyright © 2018 ChaiShushan . +// License: https://creativecommons.org/licenses/by-nc-sa/4.0/ + +#include "textflag.h" + +TEXT ·ptrToFunc(SB), NOSPLIT, $0-16 + MOVQ ptr+0(FP), AX // AX = ptr + MOVQ AX, ret+8(FP) // return AX + RET + +TEXT ·asmFunTwiceClosureAddr(SB), NOSPLIT, $0-8 + LEAQ ·asmFunTwiceClosureBody(SB), AX // AX = ·asmFunTwiceClosureBody(SB) + MOVQ AX, ret+0(FP) // return AX + RET + +TEXT ·asmFunTwiceClosureBody(SB), NOSPLIT|NEEDCTXT, $0-8 + MOVQ 8(DX), AX + ADDQ AX , AX // AX *= 2 + MOVQ AX , 8(DX) // ctx.X = AX + MOVQ AX , ret+0(FP) // return AX + RET +