Add INTEGER_MINUS and INETEGER_MULT.

This commit is contained in:
zjkree
2024-12-24 03:58:50 +01:00
parent 4cc20edf96
commit 92e353dcda
2 changed files with 144 additions and 8 deletions
+40 -5
View File
@@ -6,8 +6,7 @@ import "forge-std/console.sol";
/**
* @title Push3Interpreter
* @dev Demonstrates a minimal Push3-like interpreter that uses
* a token-based bytecode approach. We fix the assembly
* endianness issues by copying exact bytes for 2- and 4-byte reads.
* a token-based bytecode approach.
*/
contract Push3Interpreter {
// -----------------------------------------------------
@@ -21,8 +20,10 @@ contract Push3Interpreter {
}
enum OpCode {
NOOP, // 0
INTEGER_PLUS // 1
NOOP, // 0
INTEGER_PLUS, // 1
INTEGER_MINUS, // 2
INTEGER_MULT // 3
}
// -----------------------------------------------------
@@ -111,12 +112,15 @@ contract Push3Interpreter {
*/
function readUint16(bytes calldata code, uint32 start) internal pure returns (uint16 val) {
require(start + 2 <= code.length, "readUint16 out of range");
uint256 word;
assembly {
let buf := mload(0x40)
calldatacopy(buf, add(code.offset, start), 2)
let word := mload(buf)
word := mload(buf)
val := and(word, 0xffff)
}
// Not sure this is correct
val = uint16(word >> 240);
}
// -----------------------------------------------------
@@ -128,6 +132,7 @@ contract Push3Interpreter {
* 0x01 => INTEGER_PLUS
* 0x02 => INT_LITERAL => read next 4 bytes => int32
* 0x03 => SUBLIST => read next 2 bytes => subLen => parse that
* 0x04 => INTEGER_MINUS
*/
function parseSublist(bytes calldata code, uint32 off, uint32 len)
internal
@@ -187,6 +192,16 @@ contract Push3Interpreter {
break;
}
}
else if (tokenType == 0x04) {
// INTEGER_PLUS
temp[count] = makeInstruction(OpCode.INTEGER_MINUS);
count++;
}
else if (tokenType == 0x05) {
// INTEGER_PLUS
temp[count] = makeInstruction(OpCode.INTEGER_MULT);
count++;
}
else {
// unknown => NOOP
temp[count] = makeInstruction(OpCode.NOOP);
@@ -260,6 +275,26 @@ contract Push3Interpreter {
intTop++;
}
}
else if (op == OpCode.INTEGER_MINUS) {
// pop top 2 => minus
if (intTop >= 2) {
int256 a = intStack[intTop - 1];
int256 b = intStack[intTop - 2];
intTop -= 2;
intStack[intTop] = b - a;
intTop++;
}
}
else if (op == OpCode.INTEGER_MULT) {
// pop top 2 => minus
if (intTop >= 2) {
int256 a = intStack[intTop - 1];
int256 b = intStack[intTop - 2];
intTop -= 2;
intStack[intTop] = b * a;
intTop++;
}
}
}
else if (tag == CodeTag.INT_LITERAL) {
int32 val = extractInt32(topDesc);