mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 12:32:21 +00:00
commit
c9f00ebf81
@ -192,7 +192,7 @@ func MyInt_Twice(v MyInt) int {
|
||||
// func (v MyInt) Twice() int
|
||||
TEXT ·MyInt·Twice(SB), NOSPLIT, $0-16
|
||||
MOVQ a+0(FP), AX // v
|
||||
MOVQ AX, AX // AX *= 2
|
||||
ADDQ AX, AX // AX *= 2
|
||||
MOVQ AX, ret+8(FP) // return v
|
||||
RET
|
||||
```
|
||||
|
@ -167,7 +167,7 @@ var g_goid_offset = func() int64 {
|
||||
|
||||
枚举和暴力穷举虽然够直接,但是对于正在开发中的未发布的Go版本支持并不好,我们无法提前知晓开发中的某个版本的goid成员的偏移量。
|
||||
|
||||
如果是在runtime包内部,我们可以通过`unsafe.OffsetOf(g.gois)`直接获取成员的偏移量。也可以通过反射获取g结构体的类型,然后通过类型查询某个成员的偏移量。因为g结构体是一个内部类型,Go代码无法从外部包获取g结构体的类型信息。但是再Go汇编语言中,我们是可以看到全部的符号的,因此理论上我们也可以获取g结构体的类型信息。
|
||||
如果是在runtime包内部,我们可以通过`unsafe.OffsetOf(g.goid)`直接获取成员的偏移量。也可以通过反射获取g结构体的类型,然后通过类型查询某个成员的偏移量。因为g结构体是一个内部类型,Go代码无法从外部包获取g结构体的类型信息。但是在Go汇编语言中,我们是可以看到全部的符号的,因此理论上我们也可以获取g结构体的类型信息。
|
||||
|
||||
在任意的类型被定义之后,Go语言都会为该类型生成对应的类型信息。比如g结构体会生成一个`type·runtime·g`标识符表示g结构体的值类型信息,同时还有一个`type·*runtime·g`标识符表示指针类型的信息。如果g结构体带有方法,那么同时还会生成`go.itab.runtime.g`和`go.itab.*runtime.g`类型信息,用于表示带方法的类型信息。
|
||||
|
||||
@ -194,7 +194,7 @@ TEXT ·getg(SB), NOSPLIT, $32-16
|
||||
RET
|
||||
```
|
||||
|
||||
其中AX寄存器对应g指针,BX寄存器对应g结构体的类型。然后通过runtime·convT2E函数将类型转为接口。因为我们使用的不是g结构体指针类型,因此返回的接口表示的g结构体值类型。理论上我们也可以构造g指针类型的接口,但是因为Go汇编语言的限制,我们无法`type·*runtime·g`标识符。
|
||||
其中AX寄存器对应g指针,BX寄存器对应g结构体的类型。然后通过runtime·convT2E函数将类型转为接口。因为我们使用的不是g结构体指针类型,因此返回的接口表示的g结构体值类型。理论上我们也可以构造g指针类型的接口,但是因为Go汇编语言的限制,我们无法使用`type·*runtime·g`标识符。
|
||||
|
||||
基于g返回的接口,就可以容易获取goid了:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user