| 
									
										
										
										
											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
										 |  |  | // | 
					
						
							|  |  |  | // go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // 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 ( | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 	"math" | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger/glog" | 
					
						
							| 
									
										
										
										
											2014-07-22 11:54:48 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 16:58:52 +01:00
										 |  |  | // Global Debug flag indicating Debug VM (full logging) | 
					
						
							|  |  |  | var Debug bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-19 11:18:34 +01:00
										 |  |  | type Type byte | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-01-19 11:18:34 +01:00
										 |  |  | 	StdVmTy Type = iota | 
					
						
							| 
									
										
										
										
											2015-01-12 19:40:14 +01:00
										 |  |  | 	JitVmTy | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 	MaxVmTy | 
					
						
							| 
									
										
										
										
											2015-03-16 21:46:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	LogTyPretty byte = 0x1 | 
					
						
							|  |  |  | 	LogTyDiff   byte = 0x2 | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var ( | 
					
						
							|  |  |  | 	Pow256 = common.BigPow(2, 256) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	U256 = common.U256 | 
					
						
							|  |  |  | 	S256 = common.S256 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Zero = common.Big0 | 
					
						
							| 
									
										
										
										
											2015-03-28 20:30:16 +01:00
										 |  |  | 	One  = common.Big1 | 
					
						
							| 
									
										
										
										
											2015-03-16 21:46:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	max = big.NewInt(math.MaxInt64) | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-01 15:30:29 +01:00
										 |  |  | func NewVm(env Environment) VirtualMachine { | 
					
						
							|  |  |  | 	switch env.VmType() { | 
					
						
							|  |  |  | 	case JitVmTy: | 
					
						
							|  |  |  | 		return NewJitVm(env) | 
					
						
							|  |  |  | 	default: | 
					
						
							| 
									
										
										
										
											2015-04-04 12:40:11 +02:00
										 |  |  | 		glog.V(0).Infoln("unsupported vm type %d", env.VmType()) | 
					
						
							| 
									
										
										
										
											2015-02-01 15:30:29 +01:00
										 |  |  | 		fallthrough | 
					
						
							|  |  |  | 	case StdVmTy: | 
					
						
							|  |  |  | 		return New(env) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | func calcMemSize(off, l *big.Int) *big.Int { | 
					
						
							| 
									
										
										
										
											2015-03-16 11:27:38 +01:00
										 |  |  | 	if l.Cmp(common.Big0) == 0 { | 
					
						
							|  |  |  | 		return common.Big0 | 
					
						
							| 
									
										
										
										
											2014-10-14 11:48:52 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return new(big.Int).Add(off, l) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Simple helper | 
					
						
							|  |  |  | func u256(n int64) *big.Int { | 
					
						
							|  |  |  | 	return big.NewInt(n) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Mainly used for print variables and passing to Print* | 
					
						
							|  |  |  | func toValue(val *big.Int) interface{} { | 
					
						
							|  |  |  | 	// Let's assume a string on right padded zero's | 
					
						
							|  |  |  | 	b := val.Bytes() | 
					
						
							|  |  |  | 	if b[0] != 0 && b[len(b)-1] == 0x0 && b[len(b)-2] == 0x0 { | 
					
						
							|  |  |  | 		return string(b) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return val | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 22:45:03 +01:00
										 |  |  | func getData(data []byte, start, size *big.Int) []byte { | 
					
						
							|  |  |  | 	dlen := big.NewInt(int64(len(data))) | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-19 22:45:03 +01:00
										 |  |  | 	s := common.BigMin(start, dlen) | 
					
						
							|  |  |  | 	e := common.BigMin(new(big.Int).Add(s, size), dlen) | 
					
						
							|  |  |  | 	return common.RightPadBytes(data[s.Uint64():e.Uint64()], int(size.Uint64())) | 
					
						
							| 
									
										
										
										
											2015-03-13 13:44:15 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-28 20:03:25 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | func UseGas(gas, amount *big.Int) bool { | 
					
						
							|  |  |  | 	if gas.Cmp(amount) < 0 { | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Sub the amount of gas from the remaining | 
					
						
							|  |  |  | 	gas.Sub(gas, amount) | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | } |