void CSECodeGenerator::appendItem(AssemblyItem const& _item)
{
	m_generatedItems.push_back(_item);
	m_stackHeight += _item.deposit();
}
예제 #2
0
KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool _copyItem)
{
	StoreOperation op;
	if (_item.type() == Tag)
	{
		// can be ignored
	}
	else if (_item.type() != Operation)
	{
		assertThrow(_item.deposit() == 1, InvalidDeposit, "");
		if (_item.pushedValue())
			// only available after assembly stage, should not be used for optimisation
			setStackElement(++m_stackHeight, m_expressionClasses->find(*_item.pushedValue()));
		else
			setStackElement(++m_stackHeight, m_expressionClasses->find(_item, {}, _copyItem));
	}
	else
	{
		Instruction instruction = _item.instruction();
		InstructionInfo info = instructionInfo(instruction);
		if (SemanticInformation::isDupInstruction(_item))
			setStackElement(
				m_stackHeight + 1,
				stackElement(
					m_stackHeight - int(instruction) + int(Instruction::DUP1),
					_item.getLocation()
				)
			);
		else if (SemanticInformation::isSwapInstruction(_item))
			swapStackElements(
				m_stackHeight,
				m_stackHeight - 1 - int(instruction) + int(Instruction::SWAP1),
				_item.getLocation()
			);
		else if (instruction != Instruction::POP)
		{
			vector<Id> arguments(info.args);
			for (int i = 0; i < info.args; ++i)
				arguments[i] = stackElement(m_stackHeight - i, _item.getLocation());

			if (_item.instruction() == Instruction::SSTORE)
				op = storeInStorage(arguments[0], arguments[1], _item.getLocation());
			else if (_item.instruction() == Instruction::SLOAD)
				setStackElement(
					m_stackHeight + _item.deposit(),
					loadFromStorage(arguments[0], _item.getLocation())
				);
			else if (_item.instruction() == Instruction::MSTORE)
				op = storeInMemory(arguments[0], arguments[1], _item.getLocation());
			else if (_item.instruction() == Instruction::MLOAD)
				setStackElement(
					m_stackHeight + _item.deposit(),
					loadFromMemory(arguments[0], _item.getLocation())
				);
			else if (_item.instruction() == Instruction::SHA3)
				setStackElement(
					m_stackHeight + _item.deposit(),
					applySha3(arguments.at(0), arguments.at(1), _item.getLocation())
				);
			else
			{
				if (SemanticInformation::invalidatesMemory(_item.instruction()))
					resetMemory();
				if (SemanticInformation::invalidatesStorage(_item.instruction()))
					resetStorage();
				assertThrow(info.ret <= 1, InvalidDeposit, "");
				if (info.ret == 1)
					setStackElement(
						m_stackHeight + _item.deposit(),
						m_expressionClasses->find(_item, arguments, _copyItem)
					);
			}
		}
		m_stackElements.erase(
			m_stackElements.upper_bound(m_stackHeight + _item.deposit()),
			m_stackElements.end()
		);
		m_stackHeight += _item.deposit();
	}
	return op;
}