| 
									
										
										
										
											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" | 
					
						
							|  |  |  | 	"math/big" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-06 23:06:47 +02:00
										 |  |  | // 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. | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | type Stack struct { | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	data []*big.Int | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func newstack() *Stack { | 
					
						
							|  |  |  | 	return &Stack{} | 
					
						
							| 
									
										
										
										
											2015-08-06 23:06:47 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) Data() []*big.Int { | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	return st.data | 
					
						
							| 
									
										
										
										
											2015-06-10 12:23:49 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) push(d *big.Int) { | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 	// NOTE push limit (1024) is checked in baseCheck | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	//stackItem := new(big.Int).Set(d) | 
					
						
							|  |  |  | 	//st.data = append(st.data, stackItem) | 
					
						
							|  |  |  | 	st.data = append(st.data, d) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) pushN(ds ...*big.Int) { | 
					
						
							| 
									
										
										
										
											2015-10-06 23:39:43 +02:00
										 |  |  | 	st.data = append(st.data, ds...) | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) pop() (ret *big.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
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) dup(n int) { | 
					
						
							| 
									
										
										
										
											2015-07-17 23:09:36 +02:00
										 |  |  | 	st.push(new(big.Int).Set(st.data[st.len()-n])) | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) peek() *big.Int { | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	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 | 
					
						
							|  |  |  | func (st *Stack) Back(n int) *big.Int { | 
					
						
							|  |  |  | 	return st.data[st.len()-n-1] | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 15:19:51 +01:00
										 |  |  | func (st *Stack) require(n int) error { | 
					
						
							| 
									
										
										
										
											2015-03-10 00:25:27 +01:00
										 |  |  | 	if st.len() < n { | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 		return fmt.Errorf("stack underflow (%d <=> %d)", len(st.data), n) | 
					
						
							| 
									
										
										
										
											2014-12-31 11:12:40 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-27 16:09:57 +01:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2014-12-31 11:12:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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("#############") | 
					
						
							|  |  |  | } |