| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // Copyright 2014 The go-ethereum Authors | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // This file is part of the go-ethereum library. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-23 18:35:11 +02:00
										 |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							| 
									
										
										
										
											2015-07-22 18:48:40 +02:00
										 |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2015-07-07 02:54:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-18 13:31:20 +02:00
										 |  |  | package vm | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/holiman/uint256" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | var stackPool = sync.Pool{ | 
					
						
							|  |  |  | 	New: func() interface{} { | 
					
						
							|  |  |  | 		return &Stack{data: make([]uint256.Int, 0, 16)} | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 08:56:25 -04:00
										 |  |  | // Stack is an object for basic stack operations. Items popped to the stack are | 
					
						
							| 
									
										
										
										
											2015-08-06 23:06:47 +02:00
										 |  |  | // expected to be changed and modified. stack does not take care of adding newly | 
					
						
							|  |  |  | // initialised objects. | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | type Stack struct { | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | 	data []uint256.Int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func newstack() *Stack { | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | 	return stackPool.Get().(*Stack) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func returnStack(s *Stack) { | 
					
						
							|  |  |  | 	s.data = s.data[:0] | 
					
						
							|  |  |  | 	stackPool.Put(s) | 
					
						
							| 
									
										
										
										
											2015-08-06 23:06:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | // Data returns the underlying uint256.Int array. | 
					
						
							|  |  |  | func (st *Stack) Data() []uint256.Int { | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	return st.data | 
					
						
							| 
									
										
										
										
											2015-06-10 12:23:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) push(d *uint256.Int) { | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 	// NOTE push limit (1024) is checked in baseCheck | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | 	st.data = append(st.data, *d) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) pushN(ds ...uint256.Int) { | 
					
						
							|  |  |  | 	// FIXME: Is there a way to pass args by pointers. | 
					
						
							| 
									
										
										
										
											2015-10-06 23:39:43 +02:00
										 |  |  | 	st.data = append(st.data, ds...) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) pop() (ret uint256.Int) { | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	ret = st.data[len(st.data)-1] | 
					
						
							|  |  |  | 	st.data = st.data[:len(st.data)-1] | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	return | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) len() int { | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	return len(st.data) | 
					
						
							| 
									
										
										
										
											2014-08-21 18:15:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) swap(n int) { | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	st.data[st.len()-n], st.data[st.len()-1] = st.data[st.len()-1], st.data[st.len()-n] | 
					
						
							| 
									
										
										
										
											2014-08-21 18:15:09 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) dup(n int) { | 
					
						
							|  |  |  | 	st.push(&st.data[st.len()-n]) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) peek() *uint256.Int { | 
					
						
							|  |  |  | 	return &st.data[st.len()-1] | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-05 11:52:10 +01:00
										 |  |  | // Back returns the n'th item in stack | 
					
						
							| 
									
										
										
										
											2020-06-08 14:24:40 +02:00
										 |  |  | func (st *Stack) Back(n int) *uint256.Int { | 
					
						
							|  |  |  | 	return &st.data[st.len()-n-1] | 
					
						
							| 
									
										
										
										
											2017-01-05 11:52:10 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-26 08:56:25 -04:00
										 |  |  | // Print dumps the content of the stack | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) Print() { | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 	fmt.Println("### stack ###") | 
					
						
							|  |  |  | 	if len(st.data) > 0 { | 
					
						
							|  |  |  | 		for i, val := range st.data { | 
					
						
							|  |  |  | 			fmt.Printf("%-3d  %v\n", i, val) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		fmt.Println("-- empty --") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Println("#############") | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | var rStackPool = sync.Pool{ | 
					
						
							|  |  |  | 	New: func() interface{} { | 
					
						
							|  |  |  | 		return &ReturnStack{data: make([]uint32, 0, 10)} | 
					
						
							|  |  |  | 	}, | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | // ReturnStack is an object for basic return stack operations. | 
					
						
							|  |  |  | type ReturnStack struct { | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | 	data []uint32 | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func newReturnStack() *ReturnStack { | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | 	return rStackPool.Get().(*ReturnStack) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func returnRStack(rs *ReturnStack) { | 
					
						
							|  |  |  | 	rs.data = rs.data[:0] | 
					
						
							|  |  |  | 	rStackPool.Put(rs) | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | func (st *ReturnStack) push(d uint32) { | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	st.data = append(st.data, d) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-16 14:06:19 +02:00
										 |  |  | // A uint32 is sufficient as for code below 4.2G | 
					
						
							|  |  |  | func (st *ReturnStack) pop() (ret uint32) { | 
					
						
							| 
									
										
										
										
											2020-06-02 04:30:16 -06:00
										 |  |  | 	ret = st.data[len(st.data)-1] | 
					
						
							|  |  |  | 	st.data = st.data[:len(st.data)-1] | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } |