void CSECodeGenerator::appendItem(AssemblyItem const& _item) { m_generatedItems.push_back(_item); m_stackHeight += _item.deposit(); }
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; }