區塊鏈教程以太坊源碼分析core-vm-stack-memory源碼分析

來源:互聯網
上載者:User

標籤:ati   asc   expect   ror   pool   val   use   less   memory   

vm使用了stack.go裡面的對象Stack來作為虛擬機器的堆棧。memory代表了虛擬機器裡面使用的記憶體對象。
stack
比較簡單,就是用1024個big.Int的定長數組來作為堆棧的儲存。
構造

    // stack is an object for basic stack operations. Items popped to the stack are    // expected to be changed and modified. stack does not take care of adding newly    // initialised objects.    type Stack struct {        data []*big.Int    }    func newstack() *Stack {        return &Stack{data: make([]*big.Int, 0, 1024)}    }push操作    func (st *Stack) push(d *big.Int) { //追加到最末尾        // NOTE push limit (1024) is checked in baseCheck        //stackItem := new(big.Int).Set(d)        //st.data = append(st.data, stackItem)        st.data = append(st.data, d)    }    func (st *Stack) pushN(ds ...*big.Int) {        st.data = append(st.data, ds...)    }pop操作    func (st *Stack) pop() (ret *big.Int) { //從最末尾取出。        ret = st.data[len(st.data)-1]        st.data = st.data[:len(st.data)-1]        return    }交換元素的值操作,還有這種操作?    func (st *Stack) swap(n int) { 交換堆棧頂的元素和離棧頂n距離的元素的值。        st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n]    }dup操作 像複製指定位置的值到堆頂    func (st *Stack) dup(pool *intPool, n int) {        st.push(pool.get().Set(st.data[st.len()-n]))    }peek 操作. 偷看棧頂元素    func (st *Stack) peek() *big.Int {        return st.data[st.len()-1]    }Back 偷看指定位置的元素    // Back returns the n‘th item in stack    func (st *Stack) Back(n int) *big.Int {        return st.data[st.len()-n-1]    }require 保證堆棧元素的數量要大於等於n.    func (st *Stack) require(n int) error {        if st.len() < n {            return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n)        }        return nil    }intpool非常簡單. 就是256大小的 big.int的池,用來加速bit.Int的分配var checkVal = big.NewInt(-42)const poolLimit = 256// intPool is a pool of big integers that// can be reused for all big.Int operations.type intPool struct {    pool *Stack}func newIntPool() *intPool {    return &intPool{pool: newstack()}}func (p *intPool) get() *big.Int {    if p.pool.len() > 0 {        return p.pool.pop()    }    return new(big.Int)}func (p *intPool) put(is ...*big.Int) {    if len(p.pool.data) > poolLimit {        return    }    for _, i := range is {        // verifyPool is a build flag. Pool verification makes sure the integrity        // of the integer pool by comparing values to a default value.        if verifyPool {            i.Set(checkVal)        }        p.pool.push(i)    }}memory構造, memory的儲存就是byte[]. 還有一個lastGasCost的記錄.type Memory struct {    store []byte    lastGasCost uint64}func NewMemory() *Memory {    return &Memory{}}使用首先需要使用Resize分配空間// Resize resizes the memory to sizefunc (m *Memory) Resize(size uint64) {    if uint64(m.Len()) < size {        m.store = append(m.store, make([]byte, size-uint64(m.Len()))...)    }}然後使用Set來設定值// Set sets offset + size to valuefunc (m *Memory) Set(offset, size uint64, value []byte) {    // length of store may never be less than offset + size.    // The store should be resized PRIOR to setting the memory    if size > uint64(len(m.store)) {        panic("INVALID memory: store empty")    }    // It‘s possible the offset is greater than 0 and size equals 0. This is because    // the calcMemSize (common.go) could potentially return 0 when size is zero (NO-OP)    if size > 0 {        copy(m.store[offset:offset+size], value)    }}Get來取值, 一個是擷取拷貝, 一個是擷取指標.// Get returns offset + size as a new slicefunc (self *Memory) Get(offset, size int64) (cpy []byte) {    if size == 0 {        return nil    }    if len(self.store) > int(offset) {        cpy = make([]byte, size)        copy(cpy, self.store[offset:offset+size])        return    }    return}// GetPtr returns the offset + sizefunc (self *Memory) GetPtr(offset, size int64) []byte {    if size == 0 {        return nil    }    if len(self.store) > int(offset) {        return self.store[offset : offset+size]    }    return nil}一些額外的協助函數 在stack_table.go裡面func makeStackFunc(pop, push int) stackValidationFunc {    return func(stack *Stack) error {        if err := stack.require(pop); err != nil {            return err        }        if stack.len()+push-pop > int(params.StackLimit) {            return fmt.Errorf("stack limit reached %d (%d)", stack.len(), params.StackLimit)        }        return nil    }}func makeDupStackFunc(n int) stackValidationFunc {    return makeStackFunc(n, n+1)}func makeSwapStackFunc(n int) stackValidationFunc {    return makeStackFunc(n, n)}

區塊鏈教程以太坊源碼分析core-vm-stack-memory源碼分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.