mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Merge pull request #2149 from ethereum/eip-create
Introduce CREATE2 in the assembler
This commit is contained in:
		
						commit
						2491721d42
					
				| @ -1,8 +1,8 @@ | ||||
| ### 0.4.12 (unreleased) | ||||
| 
 | ||||
| Features: | ||||
|  * Assembly: renamed ``SHA3`` to `KECCAK256``. | ||||
|  * Assembly: Add ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions. | ||||
|  * Assembly: renamed ``SHA3`` to ``KECCAK256``. | ||||
|  * Assembly: Add ``CREATE2`` (EIP86), ``RETURNDATASIZE`` and ``RETURNDATACOPY`` (EIP211) instructions. | ||||
|  * AST: export all attributes to JSON format. | ||||
|  * Inline Assembly: Present proper error message when not supplying enough arguments to a functional | ||||
|    instruction. | ||||
|  | ||||
| @ -155,6 +155,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _ | ||||
| 			gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
 | ||||
| 			break; | ||||
| 		case Instruction::CREATE: | ||||
| 		case Instruction::CREATE2: | ||||
| 			if (_includeExternalCosts) | ||||
| 				// We assume that we do not know the target contract and thus, the consumption is infinite.
 | ||||
| 				gas = GasConsumption::infinite(); | ||||
|  | ||||
| @ -161,6 +161,7 @@ const std::map<std::string, Instruction> dev::solidity::c_instructions = | ||||
| 	{ "CALLCODE", Instruction::CALLCODE }, | ||||
| 	{ "RETURN", Instruction::RETURN }, | ||||
| 	{ "DELEGATECALL", Instruction::DELEGATECALL }, | ||||
| 	{ "CREATE2", Instruction::CREATE2 }, | ||||
| 	{ "REVERT", Instruction::REVERT }, | ||||
| 	{ "INVALID", Instruction::INVALID }, | ||||
| 	{ "SELFDESTRUCT", Instruction::SELFDESTRUCT } | ||||
| @ -299,7 +300,8 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo = | ||||
| 	{ Instruction::CALLCODE,	{ "CALLCODE",		0, 7, 1, true, Tier::Special } }, | ||||
| 	{ Instruction::RETURN,		{ "RETURN",			0, 2, 0, true, Tier::Zero } }, | ||||
| 	{ Instruction::DELEGATECALL,	{ "DELEGATECALL",	0, 6, 1, true, Tier::Special } }, | ||||
| 	{ Instruction::REVERT,          { "REVERT",             0, 2, 0, true, Tier::Zero } }, | ||||
| 	{ Instruction::CREATE2,		{ "CREATE2",		0, 4, 1, true, Tier::Special } }, | ||||
| 	{ Instruction::REVERT,		{ "REVERT",		0, 2, 0, true, Tier::Zero } }, | ||||
| 	{ Instruction::INVALID,		{ "INVALID",		0, 0, 0, true, Tier::Zero } }, | ||||
| 	{ Instruction::SELFDESTRUCT,	{ "SELFDESTRUCT",		0, 1, 0, true, Tier::Special } } | ||||
| }; | ||||
|  | ||||
| @ -187,6 +187,7 @@ enum class Instruction: uint8_t | ||||
| 	CALLCODE,			///< message-call with another account's code only
 | ||||
| 	RETURN,				///< halt execution returning output data
 | ||||
| 	DELEGATECALL,		///< like CALLCODE but keeps caller's value and sender
 | ||||
| 	CREATE2 = 0xfb,		///< create new account with associated code
 | ||||
| 
 | ||||
| 	REVERT = 0xfd,		///< halt execution, revert state and return output data
 | ||||
| 	INVALID = 0xfe,		///< invalid instruction for expressing runtime errors (e.g., division-by-zero)
 | ||||
|  | ||||
| @ -138,6 +138,7 @@ bool SemanticInformation::isDeterministic(AssemblyItem const& _item) | ||||
| 	case Instruction::CALLCODE: | ||||
| 	case Instruction::DELEGATECALL: | ||||
| 	case Instruction::CREATE: | ||||
| 	case Instruction::CREATE2: | ||||
| 	case Instruction::GAS: | ||||
| 	case Instruction::PC: | ||||
| 	case Instruction::MSIZE: // depends on previous writes and reads, not only on content
 | ||||
| @ -178,6 +179,7 @@ bool SemanticInformation::invalidatesStorage(Instruction _instruction) | ||||
| 	case Instruction::CALLCODE: | ||||
| 	case Instruction::DELEGATECALL: | ||||
| 	case Instruction::CREATE: | ||||
| 	case Instruction::CREATE2: | ||||
| 	case Instruction::SSTORE: | ||||
| 		return true; | ||||
| 	default: | ||||
|  | ||||
| @ -447,17 +447,25 @@ void AsmAnalyzer::expectValidType(string const& type, SourceLocation const& _loc | ||||
| 
 | ||||
| void AsmAnalyzer::warnOnFutureInstruction(solidity::Instruction _instr, SourceLocation const& _location) | ||||
| { | ||||
| 	string instr; | ||||
| 	switch (_instr) | ||||
| 	{ | ||||
| 	case solidity::Instruction::CREATE2: | ||||
| 		instr = "create2"; | ||||
| 		break; | ||||
| 	case solidity::Instruction::RETURNDATASIZE: | ||||
| 		instr = "returndatasize"; | ||||
| 		break; | ||||
| 	case solidity::Instruction::RETURNDATACOPY: | ||||
| 		m_errorReporter.warning( | ||||
| 			_location, | ||||
| 			"The RETURNDATASIZE/RETURNDATACOPY instructions are only available after " | ||||
| 			"the Metropolis hard fork. Before that they act as an invalid instruction." | ||||
| 		); | ||||
| 		instr = "returndatacopy"; | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	if (!instr.empty()) | ||||
| 		m_errorReporter.warning( | ||||
| 			_location, | ||||
| 			"The \"" + instr + "\" instruction is only available after " + | ||||
| 			"the Metropolis hard fork. Before that it acts as an invalid instruction." | ||||
| 		); | ||||
| } | ||||
|  | ||||
| @ -5793,6 +5793,14 @@ BOOST_AUTO_TEST_CASE(returndatacopy_as_variable) | ||||
| 	CHECK_WARNING_ALLOW_MULTI(text, "Variable is shadowed in inline assembly by an instruction of the same name"); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(create2_as_variable) | ||||
| { | ||||
| 	char const* text = R"( | ||||
| 		contract c { function f() { uint create2; assembly { create2(0, 0, 0, 0) }}} | ||||
| 	)"; | ||||
| 	CHECK_WARNING_ALLOW_MULTI(text, "Variable is shadowed in inline assembly by an instruction of the same name"); | ||||
| } | ||||
| 
 | ||||
| BOOST_AUTO_TEST_CASE(shadowing_warning_can_be_removed) | ||||
| { | ||||
| 	char const* text = R"( | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user