当前位置: 首页>>代码示例>>C++>>正文


C++ ArrayType::getSizeOnStack方法代码示例

本文整理汇总了C++中ArrayType::getSizeOnStack方法的典型用法代码示例。如果您正苦于以下问题:C++ ArrayType::getSizeOnStack方法的具体用法?C++ ArrayType::getSizeOnStack怎么用?C++ ArrayType::getSizeOnStack使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ArrayType的用法示例。


在下文中一共展示了ArrayType::getSizeOnStack方法的1个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: copyArrayToStorage

void ArrayUtils::copyArrayToStorage(ArrayType const& _targetType, ArrayType const& _sourceType) const
{
	// this copies source to target and also clears target if it was larger
	// need to leave "target_ref target_byte_off" on the stack at the end

	// stack layout: [source_ref] [source_byte_off] [source length] target_ref target_byte_off (top)
	solAssert(_targetType.getLocation() == ArrayType::Location::Storage, "");
	solAssert(
		_sourceType.getLocation() == ArrayType::Location::CallData ||
			_sourceType.getLocation() == ArrayType::Location::Storage,
		"Given array location not implemented."
	);

	IntegerType uint256(256);
	Type const* targetBaseType = _targetType.isByteArray() ? &uint256 : &(*_targetType.getBaseType());
	Type const* sourceBaseType = _sourceType.isByteArray() ? &uint256 : &(*_sourceType.getBaseType());

	// TODO unroll loop for small sizes

	bool sourceIsStorage = _sourceType.getLocation() == ArrayType::Location::Storage;
	bool directCopy = sourceIsStorage && sourceBaseType->isValueType() && *sourceBaseType == *targetBaseType;
	bool haveByteOffsetSource = !directCopy && sourceIsStorage && sourceBaseType->getStorageBytes() <= 16;
	bool haveByteOffsetTarget = !directCopy && targetBaseType->getStorageBytes() <= 16;
	unsigned byteOffsetSize = (haveByteOffsetSource ? 1 : 0) + (haveByteOffsetTarget ? 1 : 0);

	// stack: source_ref [source_byte_off] [source_length] target_ref target_byte_off
	// store target_ref
	// arrays always start at zero byte offset, pop offset
	m_context << eth::Instruction::POP;
	for (unsigned i = _sourceType.getSizeOnStack(); i > 0; --i)
		m_context << eth::swapInstruction(i);
	// stack: target_ref source_ref [source_byte_off] [source_length]
	if (sourceIsStorage)
		// arrays always start at zero byte offset, pop offset
		m_context << eth::Instruction::POP;
	// stack: target_ref source_ref [source_length]
	// retrieve source length
	if (_sourceType.getLocation() != ArrayType::Location::CallData || !_sourceType.isDynamicallySized())
		retrieveLength(_sourceType); // otherwise, length is already there
	// stack: target_ref source_ref source_length
	m_context << eth::Instruction::DUP3;
	// stack: target_ref source_ref source_length target_ref
	retrieveLength(_targetType);
	// stack: target_ref source_ref source_length target_ref target_length
	if (_targetType.isDynamicallySized())
		// store new target length
		m_context << eth::Instruction::DUP3 << eth::Instruction::DUP3 << eth::Instruction::SSTORE;
	if (sourceBaseType->getCategory() == Type::Category::Mapping)
	{
		solAssert(targetBaseType->getCategory() == Type::Category::Mapping, "");
		solAssert(_sourceType.getLocation() == ArrayType::Location::Storage, "");
		// nothing to copy
		m_context
			<< eth::Instruction::POP << eth::Instruction::POP
			<< eth::Instruction::POP << eth::Instruction::POP;
		m_context << u256(0);
		return;
	}
	// compute hashes (data positions)
	m_context << eth::Instruction::SWAP1;
	if (_targetType.isDynamicallySized())
		CompilerUtils(m_context).computeHashStatic();
	// stack: target_ref source_ref source_length target_length target_data_pos
	m_context << eth::Instruction::SWAP1;
	convertLengthToSize(_targetType);
	m_context << eth::Instruction::DUP2 << eth::Instruction::ADD;
	// stack: target_ref source_ref source_length target_data_pos target_data_end
	m_context << eth::Instruction::SWAP3;
	// stack: target_ref target_data_end source_length target_data_pos source_ref
	// skip copying if source length is zero
	m_context << eth::Instruction::DUP3 << eth::Instruction::ISZERO;
	eth::AssemblyItem copyLoopEndWithoutByteOffset = m_context.newTag();
	m_context.appendConditionalJumpTo(copyLoopEndWithoutByteOffset);

	if (_sourceType.getLocation() == ArrayType::Location::Storage && _sourceType.isDynamicallySized())
		CompilerUtils(m_context).computeHashStatic();
	// stack: target_ref target_data_end source_length target_data_pos source_data_pos
	m_context << eth::Instruction::SWAP2;
	convertLengthToSize(_sourceType);
	m_context << eth::Instruction::DUP3 << eth::Instruction::ADD;
	// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end
	if (haveByteOffsetTarget)
		m_context << u256(0);
	if (haveByteOffsetSource)
		m_context << u256(0);
	// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset]
	eth::AssemblyItem copyLoopStart = m_context.newTag();
	m_context << copyLoopStart;
	// check for loop condition
	m_context
		<< eth::dupInstruction(3 + byteOffsetSize) << eth::dupInstruction(2 + byteOffsetSize)
		<< eth::Instruction::GT << eth::Instruction::ISZERO;
	eth::AssemblyItem copyLoopEnd = m_context.newTag();
	m_context.appendConditionalJumpTo(copyLoopEnd);
	// stack: target_ref target_data_end source_data_pos target_data_pos source_data_end [target_byte_offset] [source_byte_offset]
	// copy
	if (sourceBaseType->getCategory() == Type::Category::Array)
	{
		solAssert(byteOffsetSize == 0, "Byte offset for array as base type.");
		m_context << eth::Instruction::DUP3;
//.........这里部分代码省略.........
开发者ID:gluk256,项目名称:cpp-ethereum,代码行数:101,代码来源:ArrayUtils.cpp


注:本文中的ArrayType::getSizeOnStack方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。