Implemented transient storage in Yul and inline assembly

This commit is contained in:
hrkrshnn 2022-07-20 13:24:16 +02:00 committed by hrkrshnn
parent cc7a14a61d
commit 8b530040cc
9 changed files with 50 additions and 1 deletions

View File

@ -305,7 +305,7 @@ YulEVMBuiltin:
| 'delegatecall' | 'staticcall' | 'return' | 'revert' | 'selfdestruct' | 'invalid'
| 'log0' | 'log1' | 'log2' | 'log3' | 'log4' | 'chainid' | 'origin' | 'gasprice'
| 'blockhash' | 'coinbase' | 'timestamp' | 'number' | 'difficulty' | 'prevrandao'
| 'gaslimit' | 'basefee';
| 'gaslimit' | 'basefee' | 'tload' | 'tstore';
YulLBrace: '{' -> pushMode(YulMode);
YulRBrace: '}' -> popMode;

View File

@ -163,6 +163,8 @@ std::map<std::string, Instruction> const solidity::evmasm::c_instructions =
{ "LOG2", Instruction::LOG2 },
{ "LOG3", Instruction::LOG3 },
{ "LOG4", Instruction::LOG4 },
{ "TLOAD", Instruction::TLOAD },
{ "TSTORE", Instruction::TSTORE },
{ "CREATE", Instruction::CREATE },
{ "CALL", Instruction::CALL },
{ "CALLCODE", Instruction::CALLCODE },
@ -312,6 +314,8 @@ static std::map<Instruction, InstructionInfo> const c_instructionInfo =
{ Instruction::LOG2, { "LOG2", 0, 4, 0, true, Tier::Special } },
{ Instruction::LOG3, { "LOG3", 0, 5, 0, true, Tier::Special } },
{ Instruction::LOG4, { "LOG4", 0, 6, 0, true, Tier::Special } },
{ Instruction::TLOAD, { "TLOAD", 0, 1, 1, false, Tier::Special} },
{ Instruction::TSTORE, { "TSTORE", 0, 2, 0, true, Tier::Special} },
{ Instruction::CREATE, { "CREATE", 0, 3, 1, true, Tier::Special } },
{ Instruction::CALL, { "CALL", 0, 7, 1, true, Tier::Special } },
{ Instruction::CALLCODE, { "CALLCODE", 0, 7, 1, true, Tier::Special } },

View File

@ -177,6 +177,9 @@ enum class Instruction: uint8_t
LOG3, ///< Makes a log entry; 3 topics.
LOG4, ///< Makes a log entry; 4 topics.
TLOAD = 0xb3, ///< https://eips.ethereum.org/EIPS/eip-1153
TSTORE = 0xb4, ///< https://eips.ethereum.org/EIPS/eip-1153
CREATE = 0xf0, ///< create a new account with associated code
CALL, ///< message-call into an account
CALLCODE, ///< message-call with another account's code only

View File

@ -486,6 +486,7 @@ bool SemanticInformation::invalidInPureFunctions(Instruction _instruction)
case Instruction::GASLIMIT:
case Instruction::STATICCALL:
case Instruction::SLOAD:
case Instruction::TLOAD:
return true;
default:
break;
@ -505,6 +506,7 @@ bool SemanticInformation::invalidInViewFunctions(Instruction _instruction)
case Instruction::LOG2:
case Instruction::LOG3:
case Instruction::LOG4:
case Instruction::TSTORE:
case Instruction::CREATE:
case Instruction::CALL:
case Instruction::CALLCODE:

View File

@ -0,0 +1,8 @@
contract C {
function f() external returns(uint a) {
assembly {
tstore(0, 13)
a := tload(0)
}
}
}

View File

@ -0,0 +1,9 @@
contract C {
function f() external pure {
assembly {
pop(tload(0))
}
}
}
// ----
// TypeError 2527: (81-89): Function declared as pure, but this expression (potentially) reads from the environment or state and thus requires "view".

View File

@ -0,0 +1,7 @@
contract C {
function f() external view returns (uint a) {
assembly {
a := tload(0)
}
}
}

View File

@ -0,0 +1,9 @@
contract C {
function f() external view {
assembly {
tstore(0, 0)
}
}
}
// ----
// TypeError 8961: (77-89): Function cannot be declared as view because this expression (potentially) modifies the state.

View File

@ -315,6 +315,13 @@ u256 EVMInstructionInterpreter::eval(
accessMemory(arg[0], arg[1]);
logTrace(_instruction, arg);
return 0;
case Instruction::TLOAD:
// TODO
return 0;
case Instruction::TSTORE:
// TODO
return 0;
// --------------- calls ---------------
case Instruction::CREATE:
accessMemory(arg[1], arg[2]);