Boolean stack implementation #18
@@ -133,48 +133,46 @@ contract Push3Interpreter {
|
|||||||
// 3. HELPER READS
|
// 3. HELPER READS
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Read `x` bytes from `code` at `start` as uint.
|
||||||
|
*/
|
||||||
|
function readUint(bytes calldata code, uint32 start, uint256 numBytes) internal pure returns (uint256 word) {
|
||||||
|
if (start + bytesNum) > code.length) revert ReadUintOutOfRange();
|
||||||
|
assembly {
|
||||||
|
let buf := mload(0x40) // free memory
|
||||||
|
// copy exactly x bytes from code into buf
|
||||||
|
calldatacopy(buf, add(code.offset, start), numBytes)
|
||||||
|
word := mload(buf)
|
||||||
|
}
|
||||||
|
word >>= 256 - numBytes * 8;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Read 4 bytes from `code` at `start` as uint32.
|
* @dev Read 4 bytes from `code` at `start` as uint32.
|
||||||
*/
|
*/
|
||||||
function readUint32(bytes calldata code, uint32 start) internal pure returns (uint32 val) {
|
function readUint32(bytes calldata code, uint32 start) internal pure returns (uint32 val) {
|
||||||
require(start + 4 <= code.length, "readUint32 out of range");
|
val = uint32(readUint(code, start, 4));
|
||||||
uint256 word;
|
|
||||||
assembly {
|
|
||||||
let buf := mload(0x40) // free memory
|
|
||||||
// copy exactly 4 bytes from code into buf
|
|
||||||
calldatacopy(buf, add(code.offset, start), 4)
|
|
||||||
word := mload(buf)
|
|
||||||
}
|
|
||||||
val = uint32(word >> 224);
|
|
||||||
}
|
|
||||||
|
|
||||||
function readBool(bytes calldata code, uint32 start) internal pure returns (bool val) {
|
|
||||||
require(start + 1 <= code.length, "readBool out of range");
|
|
||||||
uint256 word;
|
|
||||||
assembly {
|
|
||||||
let buf := mload(0x40) // free memory
|
|
||||||
// copy exactly 1 byte from code into buf
|
|
||||||
calldatacopy(buf, add(code.offset, start), 1)
|
|
||||||
// assign 1 byte to a word
|
|
||||||
word := shr(248, mload(buf))
|
|
||||||
}
|
|
||||||
val = word & 1 == 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dev Read 2 bytes from `code` at `start` as uint16.
|
* @dev Read 2 bytes from `code` at `start` as uint16.
|
||||||
*/
|
*/
|
||||||
function readUint16(bytes calldata code, uint32 start) internal pure returns (uint16 val) {
|
function readUint16(bytes calldata code, uint32 start) internal pure returns (uint16 val) {
|
||||||
require(start + 2 <= code.length, "readUint16 out of range");
|
val = uint16(readUint(code, start, 2));
|
||||||
uint256 word;
|
|
||||||
assembly {
|
|
||||||
let buf := mload(0x40)
|
|
||||||
calldatacopy(buf, add(code.offset, start), 2)
|
|
||||||
word := mload(buf)
|
|
||||||
val := and(word, 0xffff)
|
|
||||||
}
|
}
|
||||||
// Not sure this is correct
|
|
||||||
val = uint16(word >> 240);
|
/**
|
||||||
|
* @dev Read 1 byte from `code` at `start` as uint8.
|
||||||
|
*/
|
||||||
|
function readUint8(bytes calldata code, uint32 start) internal pure returns (uint8 val) {
|
||||||
|
val = uint8(readUint(code, start, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dev Read 1 byte from `code` at `start` as bool.
|
||||||
|
*/
|
||||||
|
function readBool(bytes calldata code, uint32 start) internal pure returns (bool val) {
|
||||||
|
val = readUint(code, start, 1) & 1 == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------
|
// -----------------------------------------------------
|
||||||
@@ -183,7 +181,7 @@ contract Push3Interpreter {
|
|||||||
/**
|
/**
|
||||||
* Token format is combination of ordered CodeTag and OpCode:
|
* Token format is combination of ordered CodeTag and OpCode:
|
||||||
* 0x00 => NOOP/NO_TAG
|
* 0x00 => NOOP/NO_TAG
|
||||||
* 0x01 => INSTRUCTION => TODO: decide what to do
|
* 0x01 => INSTRUCTION => read next 1 byte => OpCode
|
||||||
* 0x02 => INT_LITERAL => read next 4 bytes => int32
|
* 0x02 => INT_LITERAL => read next 4 bytes => int32
|
||||||
* 0x03 => BOOL_LITERAL => read next 1 byte => bool
|
* 0x03 => BOOL_LITERAL => read next 1 byte => bool
|
||||||
* 0x04 => SUBLIST => read next 2 bytes => subLen => parse that
|
* 0x04 => SUBLIST => read next 2 bytes => subLen => parse that
|
||||||
@@ -216,12 +214,14 @@ contract Push3Interpreter {
|
|||||||
}
|
}
|
||||||
else if (tokenType == 0x01) {
|
else if (tokenType == 0x01) {
|
||||||
// INSTRUCTION
|
// INSTRUCTION
|
||||||
// TODO: implement what is decided
|
if (cur + 1 <= endPos && (cur + 1) <= code.length) {
|
||||||
// OpCode instructionOpcode = OpCode(readUint8(code,cur));
|
uint8 opcode = readUint8(code,cur);
|
||||||
// validate instruction in range, otherwise NOOP
|
if (opcode < OPCODE_INTEGER_OFFSET || opcode > OPCODE_LAST) opcode = uint8(0); // NOOP
|
||||||
// temp[count] = makeInstruction(instructionOpcode);
|
temp[count] = makeInstruction(OpCode(opcode));
|
||||||
// count++;
|
count++;
|
||||||
break; // unimplemented
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (tokenType == 0x02) {
|
else if (tokenType == 0x02) {
|
||||||
// INT_LITERAL => 4 bytes
|
// INT_LITERAL => 4 bytes
|
||||||
|
|||||||
Reference in New Issue
Block a user