douer9399 2015-10-29 03:11
浏览 149
已采纳

Go中func append的实现在哪里?

I'm very interested in go, and trying to read go function's implementations. I found some of these function doesn't have implementations there.

Such as append or call:

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//  slice = append(slice, elem1, elem2)
//  slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//  slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

// call calls fn with a copy of the n argument bytes pointed at by arg.
// After fn returns, reflectcall copies n-retoffset result bytes
// back into arg+retoffset before returning. If copying result bytes back,
// the caller must pass the argument frame type as argtype, so that
// call can execute appropriate write barriers during the copy.
func call(argtype *rtype, fn, arg unsafe.Pointer, n uint32, retoffset uint32)

It seems not calling a C code, because using cgo needs some special comments. Where is these function's implementations?

  • 写回答

3条回答 默认 最新

  • dtziv24262 2015-10-29 04:11
    关注

    The code you are reading and citing is just dummy code to have consistent documentation. The built-in functions are, well, built into the language and, as such, are included in the code processing step (the compiler).

    Simplified what happens is: lexer will detect 'append(...)' as APPEND token, parser will translate APPEND, depending on the circumstances/parameters/environment to code, code is written as assembly and assembled. The middle step - the implementation of append - can be found in the compiler here.

    What happens to an append call is best seen when looking at the assembly of an example program. Consider this:

    b := []byte{'a'}
    b = append(b, 'b')
    println(string(b), cap(b))
    

    Running it will yield the following output:

    ab 2
    

    The append call is translated to assembly like this:

    // create new slice object
    MOVQ    BX, "".b+120(SP)       // BX contains data addr., write to b.addr
    MOVQ    BX, CX                 // store addr. in CX
    MOVQ    AX, "".b+128(SP)       // AX contains len(b) == 1, write to b.len
    MOVQ    DI, "".b+136(SP)       // DI contains cap(b) == 1, write to b.cap
    MOVQ    AX, BX                 // BX now contains len(b)
    INCQ    BX                     // BX++
    CMPQ    BX, DI                 // compare new length (2) with cap (1)
    JHI $1, 225                    // jump to grow code if len > cap
    ...
    LEAQ    (CX)(AX*1), BX         // load address of newly allocated slice entry
    MOVB    $98, (BX)              // write 'b' to loaded address
    
    // grow code, call runtime.growslice(t *slicetype, old slice, cap int)
    LEAQ    type.[]uint8(SB), BP
    MOVQ    BP, (SP)               // load parameters onto stack
    MOVQ    CX, 8(SP)
    MOVQ    AX, 16(SP)
    MOVQ    SI, 24(SP)
    MOVQ    BX, 32(SP)
    PCDATA  $0, $0
    CALL    runtime.growslice(SB)  // call
    MOVQ    40(SP), DI
    MOVQ    48(SP), R8
    MOVQ    56(SP), SI
    MOVQ    R8, AX
    INCQ    R8
    MOVQ    DI, CX
    JMP 108                        // jump back, growing done
    

    As you can see, no CALL statement to a function called append can be seen. This is the full implementation of the append call in the example code. Another call with different parameters will look differently (other registers, different parameters depending on the slice type, etc.).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效