|
|
@ -21,7 +21,7 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator; |
|
|
|
import org.apache.tuweni.bytes.Bytes; |
|
|
|
import org.apache.tuweni.bytes.Bytes; |
|
|
|
|
|
|
|
|
|
|
|
/** The Push operation. */ |
|
|
|
/** The Push operation. */ |
|
|
|
public class PushOperation extends AbstractFixedCostOperation { |
|
|
|
public class PushOperation extends AbstractOperation { |
|
|
|
|
|
|
|
|
|
|
|
/** The constant PUSH_BASE. */ |
|
|
|
/** The constant PUSH_BASE. */ |
|
|
|
public static final int PUSH_BASE = 0x5F; |
|
|
|
public static final int PUSH_BASE = 0x5F; |
|
|
@ -31,9 +31,6 @@ public class PushOperation extends AbstractFixedCostOperation { |
|
|
|
|
|
|
|
|
|
|
|
private final int length; |
|
|
|
private final int length; |
|
|
|
|
|
|
|
|
|
|
|
/** The Push operation success result. */ |
|
|
|
|
|
|
|
static final OperationResult pushSuccess = new OperationResult(3, null); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Instantiates a new Push operation. |
|
|
|
* Instantiates a new Push operation. |
|
|
|
* |
|
|
|
* |
|
|
@ -41,43 +38,28 @@ public class PushOperation extends AbstractFixedCostOperation { |
|
|
|
* @param gasCalculator the gas calculator |
|
|
|
* @param gasCalculator the gas calculator |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public PushOperation(final int length, final GasCalculator gasCalculator) { |
|
|
|
public PushOperation(final int length, final GasCalculator gasCalculator) { |
|
|
|
super( |
|
|
|
super(PUSH_BASE + length, "PUSH" + length, 0, 1, gasCalculator); |
|
|
|
PUSH_BASE + length, |
|
|
|
|
|
|
|
"PUSH" + length, |
|
|
|
|
|
|
|
0, |
|
|
|
|
|
|
|
1, |
|
|
|
|
|
|
|
gasCalculator, |
|
|
|
|
|
|
|
gasCalculator.getVeryLowTierGasCost()); |
|
|
|
|
|
|
|
this.length = length; |
|
|
|
this.length = length; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public OperationResult executeFixedCostOperation(final MessageFrame frame, final EVM evm) { |
|
|
|
public OperationResult execute(final MessageFrame frame, final EVM evm) { |
|
|
|
final byte[] code = frame.getCode().getBytes().toArrayUnsafe(); |
|
|
|
final byte[] code = frame.getCode().getBytes().toArrayUnsafe(); |
|
|
|
return staticOperation(frame, code, frame.getPC(), length); |
|
|
|
int pc = frame.getPC(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Performs Push operation. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param frame the frame |
|
|
|
|
|
|
|
* @param code the code |
|
|
|
|
|
|
|
* @param pc the pc |
|
|
|
|
|
|
|
* @param pushSize the push size |
|
|
|
|
|
|
|
* @return the operation result |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public static OperationResult staticOperation( |
|
|
|
|
|
|
|
final MessageFrame frame, final byte[] code, final int pc, final int pushSize) { |
|
|
|
|
|
|
|
int copyStart = pc + 1; |
|
|
|
int copyStart = pc + 1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long gasCost = gasCalculator().pushOperationGasCost(frame, copyStart, length, code.length); |
|
|
|
Bytes push; |
|
|
|
Bytes push; |
|
|
|
if (code.length <= copyStart) { |
|
|
|
if (code.length <= copyStart) { |
|
|
|
push = Bytes.EMPTY; |
|
|
|
push = Bytes.EMPTY; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
final int copyLength = Math.min(pushSize, code.length - pc - 1); |
|
|
|
final int copyLength = Math.min(length, code.length - pc - 1); |
|
|
|
push = Bytes.wrap(code, copyStart, copyLength); |
|
|
|
push = Bytes.wrap(code, copyStart, copyLength); |
|
|
|
} |
|
|
|
} |
|
|
|
frame.pushStackItem(push); |
|
|
|
frame.pushStackItem(push); |
|
|
|
frame.setPC(pc + pushSize); |
|
|
|
frame.setPC(pc + length); |
|
|
|
return pushSuccess; |
|
|
|
return new OperationResult(gasCost, null); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|