Beispiel #1
0
/// Emit a call to do an 'initializeArrayWithTakeFrontToBack' operation.
void irgen::emitInitializeArrayWithTakeFrontToBackCall(IRGenFunction &IGF,
                                            SILType T,
                                            Address destObject,
                                            Address srcObject,
                                            llvm::Value *count) {
  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
  llvm::Value *copyFn = IGF.emitValueWitnessForLayout(T,
                             ValueWitness::InitializeArrayWithTakeFrontToBack);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(copyFn,
      {destObject.getAddress(), srcObject.getAddress(), count, metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  call->setDoesNotThrow();
}
Beispiel #2
0
QByteArray Common::packAddress(const Address &addr)//pack a shadowsocks header
{
    QByteArray ss_header;
    QByteArray address_str = addr.getAddress().toLocal8Bit();
    QByteArray address_bin;
    quint16 port_net = htons(addr.getPort());
    QByteArray port_ns = QByteArray::fromRawData(reinterpret_cast<char *>(&port_net), 2);

    int type = addr.addressType();
    ss_header.append(static_cast<char>(type));
    switch (type) {
    case Address::ADDRTYPE_HOST://should we care if it exceeds 255?
        ss_header.append(static_cast<char>(address_str.length()));
        ss_header += address_str;
        break;
    case Address::ADDRTYPE_IPV4:
        address_bin.resize(INET_ADDRSTRLEN);
        inet_pton(AF_INET, address_str.constData(), reinterpret_cast<void *>(address_bin.data()));
        ss_header += address_bin;
        break;
    case Address::ADDRTYPE_IPV6:
        address_bin.resize(INET6_ADDRSTRLEN);
        inet_pton(AF_INET6, address_str.constData(), reinterpret_cast<void *>(address_bin.data()));
        ss_header += address_bin;
        break;
    }
    return ss_header + port_ns;
}
Beispiel #3
0
/// Emit a global variable.
Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
  auto &ti = getTypeInfo(var->getLoweredType());
  
  // If the variable is empty in all resilience domains, don't actually emit it;
  // just return undef.
  if (ti.isKnownEmpty(ResilienceExpansion::Minimal)) {
    if (DebugInfo && var->getDecl()) {
      auto Zero = llvm::ConstantInt::get(Int64Ty, 0);
      DebugTypeInfo DbgTy(var->getDecl(), var->getLoweredType().getSwiftType(),
                          Int8Ty, Size(0), Alignment(1));
      DebugInfo->emitGlobalVariableDeclaration(
          Zero, var->getDecl()->getName().str(), "", DbgTy,
          var->getLinkage() != SILLinkage::Public, SILLocation(var->getDecl()));
    }
    return ti.getUndefAddress();
  }

  /// Get the global variable.
  Address addr = getAddrOfSILGlobalVariable(var, ti,
                     var->isDefinition() ? ForDefinition : NotForDefinition);
  
  /// Add a zero initializer.
  if (var->isDefinition()) {
    auto gvar = cast<llvm::GlobalVariable>(addr.getAddress());
    gvar->setInitializer(llvm::Constant::getNullValue(gvar->getValueType()));
  }

  return addr;
}
Beispiel #4
0
/**
 * FUNCTION NAME: updateLeader
 *
 * DESCRIPTION: Update Leader information
 */
void Member::updateLeader(Address leaderAddr, std::string leaderName) {
    
    if (getLeaderAddress().compare(leaderAddr.getAddress()) == 0) return;
    std::cout << "NOTICE " << leaderEntry->getUsername() << " left the chat or crashed." << std::endl;
    std::string leader_ip_port = leaderAddr.getAddress();
    leaderEntry = new MemberListEntry(leader_ip_port, leaderName);
    
    std::cout << "NOTICE " << getLeaderName() << " is the new leader" << std::endl;
    // New leader should not be in the list
    deleteMember(leader_ip_port);
    
#ifdef DEBUGLOG
    std::cout << "\tNew Leader: " << getLeaderName() << std::endl;
#endif
    
}
Beispiel #5
0
llvm::Constant *IRGenModule::getOrCreateOutlinedDestroyFunction(
                              SILType T, const TypeInfo &ti,
                              const OutliningMetadataCollector &collector) {
  IRGenMangler mangler;
  auto manglingBits = getTypeAndGenericSignatureForManglingOutlineFunction(T);
  auto funcName = mangler.mangleOutlinedDestroyFunction(manglingBits.first,
                                                        manglingBits.second);

  auto ptrTy = ti.getStorageType()->getPointerTo();
  llvm::SmallVector<llvm::Type *, 4> paramTys;
  paramTys.push_back(ptrTy);
  collector.addMetadataParameterTypes(paramTys);

  return getOrCreateHelperFunction(funcName, ptrTy, paramTys,
      [&](IRGenFunction &IGF) {
        Explosion params = IGF.collectParameters();
        Address addr = ti.getAddressForPointer(params.claimNext());
        collector.bindMetadataParameters(IGF, params);

        ti.destroy(IGF, addr, T, true);
        
        IGF.Builder.CreateRet(addr.getAddress());
      },
      true /*setIsNoInline*/);
}
void TransactionSimicsProcessor::updateStoreSetPredictor(CacheRequestType type, Address address) {
  assert(XACT_EAGER_CD);      
  if(type == CacheRequestType_LD_XACT){
    m_xact_mgr->addToLoadAddressMap(0, SIMICS_get_program_counter(m_proc).getAddress(), address.getAddress());
  } else if (type == CacheRequestType_ST_XACT){
    m_xact_mgr->updateStorePredictor(0, address.getAddress());
  }
}
Beispiel #7
0
/// Emit a call to do a 'deallocateBuffer' operation.
void irgen::emitDeallocateBufferCall(IRGenFunction &IGF,
                                     llvm::Value *metadata,
                                     Address buffer) {
  auto fn = emitLoadOfValueWitnessFromMetadata(IGF, metadata,
                                   ValueWitness::DeallocateBuffer);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(fn, {buffer.getAddress(), metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  setHelperAttributes(call);
}
Beispiel #8
0
void irgen::emitDeallocateBufferCall(IRGenFunction &IGF,
                                     SILType T,
                                     Address buffer) {
  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
                                   ValueWitness::DeallocateBuffer);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(fn, {buffer.getAddress(), metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  setHelperAttributes(call);
}
Beispiel #9
0
/// Emit a call to the 'destructiveProjectEnumData' operation.
/// The type must be dynamically known to have enum witnesses.
void irgen::emitDestructiveProjectEnumDataCall(IRGenFunction &IGF,
                                               SILType T,
                                               Address srcObject) {
  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
                                      ValueWitness::DestructiveProjectEnumData);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(fn, {srcObject.getAddress(), metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  setHelperAttributes(call);
}
Beispiel #10
0
bool Socket::send(const Address& receiver, const void* data, int size)
{
	sockaddr_in address;
	address.sin_family = AF_INET;
	address.sin_addr.S_un.S_addr = htonl(receiver.getAddress());
	address.sin_port = htons(receiver.getPort());

	//TODO handle partial packet sending through network
	int bytesSent = sendto(m_socketHandle, (const char*) data, size, 0, (const sockaddr*) &address, sizeof(sockaddr_in));

	return bytesSent == size;
}
Beispiel #11
0
/// Emit a call to do a 'destroyArray' operation.
void irgen::emitDestroyArrayCall(IRGenFunction &IGF,
                                 SILType T,
                                 Address object,
                                 llvm::Value *count) {
  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
                                   ValueWitness::DestroyArray);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(fn, {object.getAddress(), count, metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  setHelperAttributes(call);
}
Beispiel #12
0
// peer
void Connection::connect(Address addr)
{
	m_last_recieved = porting::getTimeMs();
	//MutexAutoLock peerlock(m_peers_mutex);
	//m_peers.lock_unique_rec();
	auto node = m_peers.find(PEER_ID_SERVER);
	if(node != m_peers.end()){
		//throw ConnectionException("Already connected to a server");
		ConnectionEvent ev(CONNEVENT_CONNECT_FAILED);
		putEvent(ev);
	}

	m_enet_host = enet_host_create(NULL, 1, 0, 0, 0);
	ENetAddress address;
#if defined(ENET_IPV6)
	if (!addr.isIPv6())
		inet_pton (AF_INET6, ("::ffff:"+addr.serializeString()).c_str(), &address.host);
	else
		address.host = addr.getAddress6().sin6_addr;
#else
	if (addr.isIPv6()) {
		//throw ConnectionException("Cant connect to ipv6 address");
		ConnectionEvent ev(CONNEVENT_CONNECT_FAILED);
		putEvent(ev);
	} else {
		address.host = addr.getAddress().sin_addr.s_addr;
	}
#endif

	address.port = addr.getPort();
	ENetPeer *peer = enet_host_connect(m_enet_host, &address, CHANNEL_COUNT, 0);
	peer->data = new u16;
	*((u16*)peer->data) = PEER_ID_SERVER;

	ENetEvent event;
	int ret = enet_host_service (m_enet_host, & event, 5000);
	if (ret > 0 && event.type == ENET_EVENT_TYPE_CONNECT) {
		m_peers.set(PEER_ID_SERVER, peer);
		m_peers_address.set(PEER_ID_SERVER, addr);
	} else {
		errorstream<<"connect enet_host_service ret="<<ret<<std::endl;
		if (ret == 0) {
			ConnectionEvent ev(CONNEVENT_CONNECT_FAILED);
			putEvent(ev);
		}

		/* Either the 5 seconds are up or a disconnect event was */
		/* received. Reset the peer in the event the 5 seconds   */
		/* had run out without any significant event.            */
		enet_peer_reset(peer);
	}
}
Beispiel #13
0
void MP1Node::handleFAILNotification(Address* a){
    vector<MemberListEntry>::iterator myPos;
    //Remove node with address of FAIL
    for (myPos = memberNode->memberList.begin();
        myPos != memberNode->memberList.end();
        ++myPos) {
	    Address nodeAddr = AddrUtils::initAddress(myPos->getid(), myPos->getport());
    	if (a->getAddress() == nodeAddr.getAddress()) {
    		removeMember(myPos);
    		return;
    	}
    }
}
Beispiel #14
0
/// Initialize a relative indirectable pointer to the given value.
/// This always leaves the value in the direct state; if it's not a
/// far reference, it's the caller's responsibility to ensure that the
/// pointer ranges are sufficient.
void IRGenFunction::emitStoreOfRelativeIndirectablePointer(llvm::Value *value,
                                                           Address addr,
                                                           bool isFar) {
  value = Builder.CreatePtrToInt(value, IGM.IntPtrTy);
  auto addrAsInt =
    Builder.CreatePtrToInt(addr.getAddress(), IGM.IntPtrTy);

  auto difference = Builder.CreateSub(value, addrAsInt);
  if (!isFar) {
    difference = Builder.CreateTrunc(difference, IGM.RelativeAddressTy);
  }

  Builder.CreateStore(difference, addr);
}
Beispiel #15
0
/// Emit a call to the 'destructiveInjectEnumTag' operation.
/// The type must be dynamically known to have enum witnesses.
void irgen::emitDestructiveInjectEnumTagCall(IRGenFunction &IGF,
                                             SILType T,
                                             unsigned tag,
                                             Address srcObject) {
  auto metadata = IGF.emitTypeMetadataRefForLayout(T);
  llvm::Value *fn = IGF.emitValueWitnessForLayout(T,
                                      ValueWitness::DestructiveInjectEnumTag);
  llvm::Value *tagValue =
    llvm::ConstantInt::get(IGF.IGM.Int32Ty, tag);
  llvm::CallInst *call =
    IGF.Builder.CreateCall(fn, {srcObject.getAddress(), tagValue, metadata});
  call->setCallingConv(IGF.IGM.DefaultCC);
  setHelperAttributes(call);
}
Beispiel #16
0
// host
void Connection::serve(Address bind_addr)
{
	ENetAddress address;
#if defined(ENET_IPV6)
	address.host = bind_addr.getAddress6().sin6_addr; // in6addr_any;
#else
	address.host = bind_addr.getAddress().sin_addr.s_addr; // ENET_HOST_ANY;
#endif
	address.port = bind_addr.getPort(); // fmtodo

	m_enet_host = enet_host_create(&address, g_settings->getU16("max_users"), CHANNEL_COUNT, 0, 0);
	if (m_enet_host == NULL) {
		ConnectionEvent ev(CONNEVENT_BIND_FAILED);
		putEvent(ev);
	}
}
Beispiel #17
0
/**
 * FUNCTION NAME: nodeLoopOps
 *
 * DESCRIPTION: Check if any node hasn't responded within a timeout period and then delete
 * 				the nodes
 * 				Propagate your membership list
 */
void MP1Node::nodeLoopOps() {

	/*
	 * Your code goes here
	 */
    vector<MemberListEntry>::iterator myPos;

    //Check and remove node older than TREMOVE
    for (myPos = memberNode->memberList.begin();
        myPos != memberNode->memberList.end();
        ++myPos) {
            
            if (myPos->gettimestamp() < par->getcurrtime() - TREMOVE) {
            	// Older than TREMOVE -- Remove from memberlist and send FAIL message to other nodes
            	Address a = AddrUtils::initAddress(myPos->getid(), myPos->getport());
               	removeMember(myPos);
               	sendFAILNotification(&a);
            	myPos = memberNode->memberList.begin(); //reset iterator
            } 
        }
    
    //Gossip every TGOSSIP to PGOSSIPNODES
    
    if (par->getcurrtime() % TGOSSIP == 0 ) {
        int k = 0, n = 0;
        while (k < PGOSSIPNODES) {
                n = rand()%memberNode->memberList.size() ;
  
                Address a = AddrUtils::initAddress((*memberNode).memberList[n].getid(), 
					memberNode->memberList[n].getport());
#ifdef DEBUGLOG
                stringstream out;
                string s = a.getAddress();
                out << "Gossip ml to: " << s;
                log->LOG(&memberNode->addr, (char*) out.str().c_str());
#endif

                sendMemberList(&a, GOSSIP);

                k++;
        }
    }
    
    return;
}
Beispiel #18
0
/// Emit a global variable.
Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
  auto &type = getTypeInfo(var->getLoweredType());
  
  // If the variable is empty, don't actually emit it; just return undef.
  if (type.isKnownEmpty()) {
    return type.getUndefAddress();
  }
  
  /// Get the global variable.
  Address addr = getAddrOfSILGlobalVariable(var,
                     var->isDefinition() ? ForDefinition : NotForDefinition);
  
  /// Add a zero initializer.
  if (var->isDefinition()) {
    auto gvar = cast<llvm::GlobalVariable>(addr.getAddress());
    gvar->setInitializer(llvm::Constant::getNullValue(type.getStorageType()));
  }
  return addr;
}
Beispiel #19
0
/// Emit a global variable.
Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
  auto &ti = getTypeInfo(var->getLoweredType());
  
  // If the variable is empty in all resilience domains, don't actually emit it;
  // just return undef.
  if (ti.isKnownEmpty(ResilienceExpansion::Minimal))
    return ti.getUndefAddress();

  /// Get the global variable.
  Address addr = getAddrOfSILGlobalVariable(var, ti,
                     var->isDefinition() ? ForDefinition : NotForDefinition);
  
  /// Add a zero initializer.
  if (var->isDefinition()) {
    auto gvar = cast<llvm::GlobalVariable>(addr.getAddress());
    gvar->setInitializer(llvm::Constant::getNullValue(gvar->getValueType()));
  }

  return addr;
}
Beispiel #20
0
llvm::Constant *IRGenModule::getOrCreateOutlinedCopyAddrHelperFunction(
                              SILType T, const TypeInfo &ti,
                              const OutliningMetadataCollector &collector,
                              StringRef funcName,
                              CopyAddrHelperGenerator generator) {
  auto ptrTy = ti.getStorageType()->getPointerTo();

  llvm::SmallVector<llvm::Type *, 4> paramTys;
  paramTys.push_back(ptrTy);
  paramTys.push_back(ptrTy);
  collector.addMetadataParameterTypes(paramTys);

  return getOrCreateHelperFunction(funcName, ptrTy, paramTys,
      [&](IRGenFunction &IGF) {
        auto params = IGF.collectParameters();
        Address src = ti.getAddressForPointer(params.claimNext());
        Address dest = ti.getAddressForPointer(params.claimNext());
        collector.bindMetadataParameters(IGF, params);
        generator(IGF, dest, src, T, ti);
        IGF.Builder.CreateRet(dest.getAddress());
      },
      true /*setIsNoInline*/);
}
//pack a shadowsocks header
std::string Common::packAddress(const Address &addr)
{
    std::string portNs(2, '\0');
    qToBigEndian(addr.getPort(), reinterpret_cast<uchar*>(&portNs[0]));

    std::string addrBin;
    const Address::ATYP type = addr.addressType();
    if (type == Address::HOST) {
        const std::string& addressString = addr.getAddress();
        //can't be longer than 255
        addrBin = static_cast<char>(addressString.length()) + addressString;
    } else if (type == Address::IPV4) {
        uint32_t ipv4Address = qToBigEndian(addr.getFirstIP().toIPv4Address());
        addrBin = std::string(reinterpret_cast<char*>(&ipv4Address), 4);
    } else {
        //Q_IPV6ADDR is a 16-unsigned-char struct (big endian)
        Q_IPV6ADDR ipv6Address = addr.getFirstIP().toIPv6Address();
        addrBin = std::string(reinterpret_cast<char*>(ipv6Address.c), 16);
    }

    char typeChar = static_cast<char>(type);
    return typeChar + addrBin + portNs;
}
Beispiel #22
0
/**
 * FUNCTION NAME: nodeLoopOps
 *
 * DESCRIPTION: Check if any node hasn't responded within a timeout period and then delete
 * 				the nodes
 * 				Propagate your membership list
 */
void MP1Node::nodeLoopOps() {
		int timeout = 5;

		stringstream ss;
		for (vector<MemberListEntry>::iterator it = memberNode->memberList.begin(); it != memberNode->memberList.end(); it++) {
			//ss << "Current: " << par->getcurrtime() << " ts: " << it->timestamp << " id: "<< it->id;
		    //log->LOG(&memberNode->addr, ss.str().c_str());
			//ss.str("");
			if (par->getcurrtime() - it->timestamp > timeout) {
				Address addr = AddressFromMLE(&(*it));
				ss << "Timing out " << addr.getAddress();
				log->LOG(&memberNode->addr, ss.str().c_str());
				ss.str("");
				
				vector<MemberListEntry>::iterator next_it = it;
				vector<MemberListEntry>::iterator next_next_it = it+1;
				for (next_it = it; next_next_it != memberNode->memberList.end(); next_it++, next_next_it++) {
					*next_it = *next_next_it;
				}
				memberNode->memberList.resize(memberNode->memberList.size()-1);
				it -= 1;
				LogMemberList();
				log->logNodeRemove(&memberNode->addr, &addr);
			}
	}
		/*
		 * Your code goes here
		 */
		//log->LOG(&memberNode->addr, "Looping.");

		UpdateMemberList(&memberNode->addr, ++memberNode->heartbeat);

		SendHBSomewhere(&memberNode->addr, 
						memberNode->heartbeat);
		return;
}
Beispiel #23
0
	void Run()
	{
		const int port = 30003;
		UDPSocket socket;
		socket.Bind(port);

		const char sendbuffer[] = "hello world!";
		socket.Send(Address(127,0,0,1,port), sendbuffer, sizeof(sendbuffer));

		sleep_ms(50);

		char rcvbuffer[256];
		memset(rcvbuffer, 0, sizeof(rcvbuffer));
		Address sender;
		for(;;)
		{
			int bytes_read = socket.Receive(sender, rcvbuffer, sizeof(rcvbuffer));
			if(bytes_read < 0)
				break;
		}
		//FIXME: This fails on some systems
		assert(strncmp(sendbuffer, rcvbuffer, sizeof(sendbuffer))==0);
		assert(sender.getAddress() == Address(127,0,0,1, 0).getAddress());
	}
Beispiel #24
0
void IRGenFunction::emitMemCpy(Address dest, Address src, llvm::Value *size) {
  // Map over to the inferior design of the LLVM intrinsic.
  emitMemCpy(dest.getAddress(), src.getAddress(), size,
             std::min(dest.getAlignment(), src.getAlignment()));
}
void PyriteDriver::permissionChangeCallback(NodeID proc, const Address& addr,
                                            AccessPermission old_perm, AccessPermission new_perm) {
  assert(addr.isBlockAligned());
  g_processors_vec[proc]->cachePermissionChangeNotification(addr.getAddress(), old_perm, new_perm);
}
Beispiel #26
0
/// Emit a checked cast to a protocol or protocol composition.
void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF,
                                  llvm::Value *value,
                                  SILType srcType,
                                  SILType destType,
                                  CheckedCastMode mode,
                                  Optional<MetatypeRepresentation> metatypeKind,
                                  Explosion &ex) {
  auto srcInstanceType = srcType.getSwiftRValueType();
  auto destInstanceType = destType.getSwiftRValueType();
  while (auto metatypeType = dyn_cast<ExistentialMetatypeType>(
           destInstanceType)) {
    destInstanceType = metatypeType.getInstanceType();
    srcInstanceType = cast<AnyMetatypeType>(srcInstanceType).getInstanceType();
  }

  auto layout = destInstanceType.getExistentialLayout();

  // Look up witness tables for the protocols that need them and get
  // references to the ObjC Protocol* values for the objc protocols.
  SmallVector<llvm::Value*, 4> objcProtos;
  SmallVector<llvm::Value*, 4> witnessTableProtos;

  bool hasClassConstraint = layout.requiresClass();
  bool hasClassConstraintByProtocol = false;

  bool hasSuperclassConstraint = bool(layout.superclass);

  for (auto protoTy : layout.getProtocols()) {
    auto *protoDecl = protoTy->getDecl();

    // If the protocol introduces a class constraint, track whether we need
    // to check for it independent of protocol witnesses.
    if (protoDecl->requiresClass()) {
      assert(hasClassConstraint);
      hasClassConstraintByProtocol = true;
    }

    if (Lowering::TypeConverter::protocolRequiresWitnessTable(protoDecl)) {
      auto descriptor = emitProtocolDescriptorRef(IGF, protoDecl);
      witnessTableProtos.push_back(descriptor);
    }

    if (protoDecl->isObjC())
      objcProtos.push_back(emitReferenceToObjCProtocol(IGF, protoDecl));
  }
  
  llvm::Type *resultType;
  if (metatypeKind) {
    switch (*metatypeKind) {
    case MetatypeRepresentation::Thin:
      llvm_unreachable("can't cast to thin metatype");
    case MetatypeRepresentation::Thick:
      resultType = IGF.IGM.TypeMetadataPtrTy;
      break;
    case MetatypeRepresentation::ObjC:
      resultType = IGF.IGM.ObjCClassPtrTy;
      break;
    }
  } else {
    auto schema = IGF.getTypeInfo(destType).getSchema();
    resultType = schema[0].getScalarType();
  }

  // The source of a scalar cast is statically known to be a class or a
  // metatype, so we only have to check the class constraint in two cases:
  //
  // 1) The destination type has an explicit superclass constraint that is
  //    more derived than what the source type is known to be.
  //
  // 2) We are casting between metatypes, in which case the source might
  //    be a non-class metatype.
  bool checkClassConstraint = false;
  if ((bool)metatypeKind &&
      hasClassConstraint &&
      !hasClassConstraintByProtocol &&
      !srcInstanceType->mayHaveSuperclass())
    checkClassConstraint = true;

  // If the source has an equal or more derived superclass constraint than
  // the destination, we can elide the superclass check.
  //
  // Note that destInstanceType is always an existential type, so calling
  // getSuperclass() returns the superclass constraint of the existential,
  // not the superclass of some concrete class.
  bool checkSuperclassConstraint =
    hasSuperclassConstraint &&
    !destInstanceType->getSuperclass()->isExactSuperclassOf(srcInstanceType);

  if (checkSuperclassConstraint)
    checkClassConstraint = true;

  llvm::Value *resultValue = value;

  // If we don't have anything we really need to check, then trivially succeed.
  if (objcProtos.empty() && witnessTableProtos.empty() &&
      !checkClassConstraint) {
    resultValue = IGF.Builder.CreateBitCast(value, resultType);
    ex.add(resultValue);
    return;
  }

  // Check the ObjC protocol conformances if there were any.
  llvm::Value *objcCast = nullptr;
  if (!objcProtos.empty()) {
    // Get the ObjC instance or class object to check for these conformances.
    llvm::Value *objcObject;
    if (metatypeKind) {
      switch (*metatypeKind) {
      case MetatypeRepresentation::Thin:
        llvm_unreachable("can't cast to thin metatype");
      case MetatypeRepresentation::Thick: {
        // The metadata might be for a non-class type, which wouldn't have
        // an ObjC class object.
        objcObject = nullptr;
        break;
      }
      case MetatypeRepresentation::ObjC:
        // Metatype is already an ObjC object.
        objcObject = value;
        break;
      }
    } else {
      // Class instance is already an ObjC object.
      objcObject = value;
    }
    if (objcObject)
      objcObject = IGF.Builder.CreateBitCast(objcObject,
                                             IGF.IGM.UnknownRefCountedPtrTy);
    
    // Pick the cast function based on the cast mode and on whether we're
    // casting a Swift metatype or ObjC object.
    llvm::Constant *castFn;
    switch (mode) {
    case CheckedCastMode::Unconditional:
      castFn = objcObject
        ? IGF.IGM.getDynamicCastObjCProtocolUnconditionalFn()
        : IGF.IGM.getDynamicCastTypeToObjCProtocolUnconditionalFn();
      break;
    case CheckedCastMode::Conditional:
      castFn = objcObject
        ? IGF.IGM.getDynamicCastObjCProtocolConditionalFn()
        : IGF.IGM.getDynamicCastTypeToObjCProtocolConditionalFn();
      break;
    }
    llvm::Value *objcCastObject = objcObject ? objcObject : value;
    
    Address protoRefsBuf = IGF.createAlloca(
                                        llvm::ArrayType::get(IGF.IGM.Int8PtrTy,
                                                             objcProtos.size()),
                                        IGF.IGM.getPointerAlignment(),
                                        "objc_protocols");
    protoRefsBuf = IGF.Builder.CreateBitCast(protoRefsBuf,
                                             IGF.IGM.Int8PtrPtrTy);

    for (unsigned index : indices(objcProtos)) {
      Address protoRefSlot = IGF.Builder.CreateConstArrayGEP(
                                                     protoRefsBuf, index,
                                                     IGF.IGM.getPointerSize());
      IGF.Builder.CreateStore(objcProtos[index], protoRefSlot);
      ++index;
    }

    
    auto cc = IGF.IGM.DefaultCC;
    if (auto fun = dyn_cast<llvm::Function>(castFn))
      cc = fun->getCallingConv();


    auto call = IGF.Builder.CreateCall(
        castFn,
        {objcCastObject, IGF.IGM.getSize(Size(objcProtos.size())),
         protoRefsBuf.getAddress()});
    call->setCallingConv(cc);
    objcCast = call;
    resultValue = IGF.Builder.CreateBitCast(objcCast, resultType);
  }

  // If we don't need to look up any witness tables, we're done.
  if (witnessTableProtos.empty() && !checkClassConstraint) {
    ex.add(resultValue);
    return;
  }

  // If we're doing a conditional cast, and the ObjC protocol checks failed,
  // then the cast is done.
  Optional<ConditionalDominanceScope> condition;
  llvm::BasicBlock *origBB = nullptr, *successBB = nullptr, *contBB = nullptr;
  if (!objcProtos.empty()) {
    switch (mode) {
    case CheckedCastMode::Unconditional:
      break;
    case CheckedCastMode::Conditional: {
      origBB = IGF.Builder.GetInsertBlock();
      successBB = IGF.createBasicBlock("success");
      contBB = IGF.createBasicBlock("cont");
      auto isNull = IGF.Builder.CreateICmpEQ(objcCast,
                               llvm::ConstantPointerNull::get(
                                 cast<llvm::PointerType>(objcCast->getType())));
      IGF.Builder.CreateCondBr(isNull, contBB, successBB);
      IGF.Builder.emitBlock(successBB);
      condition.emplace(IGF);
    }
    }
  }

  // Get the Swift type metadata for the type.
  llvm::Value *metadataValue;
  if (metatypeKind) {
    switch (*metatypeKind) {
    case MetatypeRepresentation::Thin:
      llvm_unreachable("can't cast to thin metatype");
    case MetatypeRepresentation::Thick:
      // The value is already a native metatype.
      metadataValue = value;
      break;
    case MetatypeRepresentation::ObjC:
      // Get the type metadata from the ObjC class, which may be a wrapper.
      metadataValue = emitObjCMetadataRefForMetadata(IGF, value);
    }
  } else {
    // Get the type metadata for the instance.
    metadataValue = emitDynamicTypeOfHeapObject(IGF, value, srcType);
  }

  // Look up witness tables for the protocols that need them.
  auto fn = emitExistentialScalarCastFn(IGF.IGM,
                                        witnessTableProtos.size(),
                                        mode,
                                        checkClassConstraint,
                                        checkSuperclassConstraint);

  llvm::SmallVector<llvm::Value *, 4> args;

  if (resultValue->getType() != IGF.IGM.Int8PtrTy)
    resultValue = IGF.Builder.CreateBitCast(resultValue, IGF.IGM.Int8PtrTy);
  args.push_back(resultValue);

  args.push_back(metadataValue);

  if (checkSuperclassConstraint)
    args.push_back(IGF.emitTypeMetadataRef(CanType(layout.superclass)));

  for (auto proto : witnessTableProtos)
    args.push_back(proto);

  auto valueAndWitnessTables = IGF.Builder.CreateCall(fn, args);

  resultValue = IGF.Builder.CreateExtractValue(valueAndWitnessTables, 0);
  if (resultValue->getType() != resultType)
    resultValue = IGF.Builder.CreateBitCast(resultValue, resultType);
  ex.add(resultValue);

  for (unsigned i = 0, e = witnessTableProtos.size(); i < e; ++i) {
    auto wt = IGF.Builder.CreateExtractValue(valueAndWitnessTables, i + 1);
    ex.add(wt);
  }

  // If we had conditional ObjC checks, join the failure paths.
  if (contBB) {
    condition.reset();
    IGF.Builder.CreateBr(contBB);
    IGF.Builder.emitBlock(contBB);
    
    // Return null on the failure path.
    Explosion successEx = std::move(ex);
    ex.reset();
    
    while (!successEx.empty()) {
      auto successVal = successEx.claimNext();
      auto failureVal = llvm::Constant::getNullValue(successVal->getType());
      auto phi = IGF.Builder.CreatePHI(successVal->getType(), 2);
      phi->addIncoming(successVal, successBB);
      phi->addIncoming(failureVal, origBB);
      ex.add(phi);
    }
  }
}
Beispiel #27
0
/// Emit a checked cast to a protocol or protocol composition.
void irgen::emitScalarExistentialDowncast(IRGenFunction &IGF,
                                  llvm::Value *value,
                                  SILType srcType,
                                  SILType destType,
                                  CheckedCastMode mode,
                                  Optional<MetatypeRepresentation> metatypeKind,
                                  Explosion &ex) {
  SmallVector<ProtocolDecl*, 4> allProtos;
  destType.getSwiftRValueType().getAnyExistentialTypeProtocols(allProtos);

  // Look up witness tables for the protocols that need them and get
  // references to the ObjC Protocol* values for the objc protocols.
  SmallVector<llvm::Value*, 4> objcProtos;
  SmallVector<llvm::Value*, 4> witnessTableProtos;

  bool hasClassConstraint = false;
  bool hasClassConstraintByProtocol = false;

  for (auto proto : allProtos) {
    // If the protocol introduces a class constraint, track whether we need
    // to check for it independent of protocol witnesses.
    if (proto->requiresClass()) {
      hasClassConstraint = true;
      if (proto->getKnownProtocolKind()
          && *proto->getKnownProtocolKind() == KnownProtocolKind::AnyObject) {
        // AnyObject only requires that the type be a class.
        continue;
      }
      
      // If this protocol is class-constrained but not AnyObject, checking its
      // conformance will check the class constraint too.
      hasClassConstraintByProtocol = true;
    }

    if (Lowering::TypeConverter::protocolRequiresWitnessTable(proto)) {
      auto descriptor = emitProtocolDescriptorRef(IGF, proto);
      witnessTableProtos.push_back(descriptor);
    }

    if (!proto->isObjC())
      continue;

    objcProtos.push_back(emitReferenceToObjCProtocol(IGF, proto));
  }
  
  llvm::Type *resultType;
  if (metatypeKind) {
    switch (*metatypeKind) {
    case MetatypeRepresentation::Thin:
      llvm_unreachable("can't cast to thin metatype");
    case MetatypeRepresentation::Thick:
      resultType = IGF.IGM.TypeMetadataPtrTy;
      break;
    case MetatypeRepresentation::ObjC:
      resultType = IGF.IGM.ObjCClassPtrTy;
      break;
    }
  } else {
    auto schema = IGF.getTypeInfo(destType).getSchema();
    resultType = schema[0].getScalarType();
  }
  // We only need to check the class constraint for metatype casts where
  // no protocol conformance indirectly requires the constraint for us.
  bool checkClassConstraint =
    (bool)metatypeKind && hasClassConstraint && !hasClassConstraintByProtocol;

  llvm::Value *resultValue = value;

  // If we don't have anything we really need to check, then trivially succeed.
  if (objcProtos.empty() && witnessTableProtos.empty() &&
      !checkClassConstraint) {
    resultValue = IGF.Builder.CreateBitCast(value, resultType);
    ex.add(resultValue);
    return;
  }

  // Check the ObjC protocol conformances if there were any.
  llvm::Value *objcCast = nullptr;
  if (!objcProtos.empty()) {
    // Get the ObjC instance or class object to check for these conformances.
    llvm::Value *objcObject;
    if (metatypeKind) {
      switch (*metatypeKind) {
      case MetatypeRepresentation::Thin:
        llvm_unreachable("can't cast to thin metatype");
      case MetatypeRepresentation::Thick: {
        // The metadata might be for a non-class type, which wouldn't have
        // an ObjC class object.
        objcObject = nullptr;
        break;
      }
      case MetatypeRepresentation::ObjC:
        // Metatype is already an ObjC object.
        objcObject = value;
        break;
      }
    } else {
      // Class instance is already an ObjC object.
      objcObject = value;
    }
    if (objcObject)
      objcObject = IGF.Builder.CreateBitCast(objcObject,
                                             IGF.IGM.UnknownRefCountedPtrTy);
    
    // Pick the cast function based on the cast mode and on whether we're
    // casting a Swift metatype or ObjC object.
    llvm::Value *castFn;
    switch (mode) {
    case CheckedCastMode::Unconditional:
      castFn = objcObject
        ? IGF.IGM.getDynamicCastObjCProtocolUnconditionalFn()
        : IGF.IGM.getDynamicCastTypeToObjCProtocolUnconditionalFn();
      break;
    case CheckedCastMode::Conditional:
      castFn = objcObject
        ? IGF.IGM.getDynamicCastObjCProtocolConditionalFn()
        : IGF.IGM.getDynamicCastTypeToObjCProtocolConditionalFn();
      break;
    }
    llvm::Value *objcCastObject = objcObject ? objcObject : value;
    
    Address protoRefsBuf = IGF.createAlloca(
                                        llvm::ArrayType::get(IGF.IGM.Int8PtrTy,
                                                             objcProtos.size()),
                                        IGF.IGM.getPointerAlignment(),
                                        "objc_protocols");
    protoRefsBuf = IGF.Builder.CreateBitCast(protoRefsBuf,
                                             IGF.IGM.Int8PtrPtrTy);

    for (unsigned index : indices(objcProtos)) {
      Address protoRefSlot = IGF.Builder.CreateConstArrayGEP(
                                                     protoRefsBuf, index,
                                                     IGF.IGM.getPointerSize());
      IGF.Builder.CreateStore(objcProtos[index], protoRefSlot);
      ++index;
    }

    
    objcCast = IGF.Builder.CreateCall(
        castFn,
        {objcCastObject, IGF.IGM.getSize(Size(objcProtos.size())),
         protoRefsBuf.getAddress()});
    resultValue = IGF.Builder.CreateBitCast(objcCast, resultType);
  }

  // If we don't need to look up any witness tables, we're done.
  if (witnessTableProtos.empty() && !checkClassConstraint) {
    ex.add(resultValue);
    return;
  }

  // If we're doing a conditional cast, and the ObjC protocol checks failed,
  // then the cast is done.
  Optional<ConditionalDominanceScope> condition;
  llvm::BasicBlock *origBB = nullptr, *successBB = nullptr, *contBB = nullptr;
  if (!objcProtos.empty()) {
    switch (mode) {
    case CheckedCastMode::Unconditional:
      break;
    case CheckedCastMode::Conditional: {
      origBB = IGF.Builder.GetInsertBlock();
      successBB = IGF.createBasicBlock("success");
      contBB = IGF.createBasicBlock("cont");
      auto isNull = IGF.Builder.CreateICmpEQ(objcCast,
                               llvm::ConstantPointerNull::get(
                                 cast<llvm::PointerType>(objcCast->getType())));
      IGF.Builder.CreateCondBr(isNull, contBB, successBB);
      IGF.Builder.emitBlock(successBB);
      condition.emplace(IGF);
    }
    }
  }

  // Get the Swift type metadata for the type.
  llvm::Value *metadataValue;
  if (metatypeKind) {
    switch (*metatypeKind) {
    case MetatypeRepresentation::Thin:
      llvm_unreachable("can't cast to thin metatype");
    case MetatypeRepresentation::Thick:
      // The value is already a native metatype.
      metadataValue = value;
      break;
    case MetatypeRepresentation::ObjC:
      // Get the type metadata from the ObjC class, which may be a wrapper.
      metadataValue = emitObjCMetadataRefForMetadata(IGF, value);
    }
  } else {
    // Get the type metadata for the instance.
    metadataValue = emitDynamicTypeOfHeapObject(IGF, value, srcType);
  }

  // Look up witness tables for the protocols that need them.
  auto fn = emitExistentialScalarCastFn(IGF.IGM, witnessTableProtos.size(),
                                        mode, checkClassConstraint);

  llvm::SmallVector<llvm::Value *, 4> args;

  if (resultValue->getType() != IGF.IGM.Int8PtrTy)
    resultValue = IGF.Builder.CreateBitCast(resultValue, IGF.IGM.Int8PtrTy);
  args.push_back(resultValue);

  args.push_back(metadataValue);
  for (auto proto : witnessTableProtos)
    args.push_back(proto);

  auto valueAndWitnessTables = IGF.Builder.CreateCall(fn, args);

  resultValue = IGF.Builder.CreateExtractValue(valueAndWitnessTables, 0);
  if (resultValue->getType() != resultType)
    resultValue = IGF.Builder.CreateBitCast(resultValue, resultType);
  ex.add(resultValue);

  for (unsigned i = 0, e = witnessTableProtos.size(); i < e; ++i) {
    auto wt = IGF.Builder.CreateExtractValue(valueAndWitnessTables, i + 1);
    ex.add(wt);
  }

  // If we had conditional ObjC checks, join the failure paths.
  if (contBB) {
    condition.reset();
    IGF.Builder.CreateBr(contBB);
    IGF.Builder.emitBlock(contBB);
    
    // Return null on the failure path.
    Explosion successEx = std::move(ex);
    ex.reset();
    
    while (!successEx.empty()) {
      auto successVal = successEx.claimNext();
      auto failureVal = llvm::Constant::getNullValue(successVal->getType());
      auto phi = IGF.Builder.CreatePHI(successVal->getType(), 2);
      phi->addIncoming(successVal, successBB);
      phi->addIncoming(failureVal, origBB);
      ex.add(phi);
    }
  }
}
Beispiel #28
0
string Handler::process(Address & from_addr, string recv_msg) {
    
#ifdef DEBUGLOG
    std::cout << "\tHandling message: " + recv_msg << " from: " << from_addr.getAddress() << std::endl;
#endif
    
    std::string send_msg;
    if (recv_msg.empty()) return "";
    
    char cstr[MAXBUFLEN];
    strcpy(cstr, recv_msg.c_str());
    char * msg_type = strtok(cstr, "#");

#ifdef DEBUGLOG
    std::cout << "\tMessage Type: " << msg_type << std::endl;
#endif
    
    Member * nodeMember = node->getMember();
    
    if (recv_msg.find("#") == 0) { // Start with a #
        
        if (strcmp(msg_type, D_M_ADDNODE) == 0) {
            
            // received: #ADDNODE#SEQ#ip#port#name
            int param_seq = atoi(strtok(NULL, "#"));
            std::string param_ip(strtok(NULL, "#"));
            std::string param_port(strtok(NULL, "#"));
            std::string param_name(strtok(NULL, "#"));
            std::string param_value(param_ip + "#" + param_port + "#" + param_name);
            node->m_queue->push(std::make_pair(param_seq, "#"+std::string(msg_type)+"#"+param_value));
            node->m_queue->pop();
            return "OK";

        } else if (strcmp(msg_type, D_M_MSG) == 0) {
            
            // received: #MSG#SEQ#username::Message
            int param_seq = atoi(strtok(NULL, "#"));
            std::string param_value(strtok(NULL, "#"));
            node->m_queue->push(std::make_pair(param_seq, "#"+std::string(msg_type)+"#"+param_value));
            //node->addMessage(param_value);
            node->m_queue->pop();
            return "OK";
        } else if (strcmp(msg_type, D_LEAVEANNO) == 0) {
            // TODO: received: #LEAVEANNO#seq#name#ip:port sent by leader
            int param_seq = atoi(strtok(NULL, "#"));
            std::string param_name_addr(strtok(NULL, "#"));
            node->m_queue->push(std::make_pair(param_seq, "#"+std::string(msg_type)+"#"+param_name_addr));
            node->m_queue->pop();
            
            return "OK";
        }
        
    } else {
        
        if (strcmp(msg_type, D_CHAT) == 0) {

            // received: CHAT#port#Seq#Message - From node to sequencer
            std::string port(strtok(NULL, "#"));
            std::string seq_str(strtok (NULL, "#"));
            std::string msg(strtok (NULL, "#"));
            int seq = stoi(seq_str);
            
            //std::cout << "\tD_CHAT" << seq  << " " + seq_str << std::endl;
            
            if (nodeMember->isLeader()) { // Only leader can multicast messages
                std::string address_port = from_addr.getAddressIp()+":"+port;
    
                // Check the existence
                auto & msg_seen = node->message_seen;
                if (msg_seen.find(address_port) == msg_seen.end()) {
                    msg_seen[address_port] = 0;
                }
     
                // Check the sequence number
                //std::cout << "current count is " << msg_seen[address_port] << std::endl;
                if (seq == (msg_seen[address_port] + 1)) {
                    // msg to be sent: #MSG#SEQ#username#Message
                    std::string message = msg;
                    node->multicastMsg(message, D_M_MSG);
                    msg_seen[address_port]++;
                    return "OK";
                } else if (seq > (msg_seen[address_port] + 1)) {
                    return std::to_string(msg_seen[address_port] + 1);
                }
                
            }

            return "OK";
            
        } else if (strcmp(msg_type, D_JOINREQ) == 0) {

            if (nodeMember->isLeader()) { // I am the leader

                // received: JOINREQ#PORT#name
                // First need to add this member to the list (should not exist)
                // If it's a multi-threaded server, seq number should be sync with other message handling
                std::string recv_port(strtok (NULL, "#"));
                std::string recv_name(strtok (NULL, "#"));

                // #ADDNODE#SEQ#ip#port#name, multicast addnode message from the sequencer
                // This message must be delivered once (at least onece)
                std::string message_addmember = from_addr.getAddressIp() + "#" + recv_port + "#" + recv_name;

                // Start a thread to do the multicast to avoid blocking self
                node->multicastMsg(message_addmember, D_M_ADDNODE);
                
                std::string member_addr = from_addr.getAddressIp() + ":" + recv_port;
                std::string member_name = recv_name;
                
                node->addMember(member_addr, member_name, false);

                int initSeq = node->m_queue->getSequenceSeen();
                // send JOINLIST#initSeq#ip1:port1:name1:ip2:port2:name2...
                std::string message = std::string(D_JOINLIST) + "#" + std::to_string(initSeq) +
                "#" + node->getUsername() + "#" + nodeMember->getMemberList();
#ifdef DEBUGLOG
                std::cout << "\tHandling Returns: " << message << std::endl;
#endif
                return message;
                
            } else {

                // received: JOINLEADER#LEADERIP#LEADERPORT
                // send back leader address - don't care failure, they can retry
                std::string message = std::string(D_JOINLEADER) + "#" + nodeMember->getLeaderAddressIp()
                + "#" + nodeMember->getLeaderAddressPort() + "#" + nodeMember->getLeaderName();
                return message;

            }
        } else if (strcmp(msg_type, D_HEARTBEAT) == 0) {
            
            // received: HEARTBEAT#port
            // know node at from_addr is still there, update heartbeat for node at from_addr
            std::string node_addr(strtok(NULL, "#"));
            time_t timev;
            time(&timev);
            nodeMember->updateHeartBeat(node_addr, timev);
#ifdef DEBUGLOG
            std::cout << "HeartBeat updated " << nodeMember->getHeartBeat(node_addr) << std::endl;
#endif
            return "OK";

        } else if (strcmp(msg_type, D_ELECTION) == 0) {
            
            // TODO: received: ELECTION#ip:port
            std::string heardFrom(strtok(NULL, "#"));
            
            // If hears D_ELECTION from a process with a higher ID,
            if(heardFrom.compare(nodeMember->getAddress()) > 0) {

                std::cout << "\tElection: This should never happen " << heardFrom << std::endl;

             } else {
                 
                 std::cout << "\tElection: heard from someone smaller... " << heardFrom << std::endl;
                 // If hears D_ELECTION from a process with a lower ID, send back OK and startElection myself
                 // node->sendNotice(std::string(D_ANSWER) + "#" + nodeMember->getAddress(), heardFrom);
                 std::thread electionThread(&DNode::startElection, node);
                 electionThread.detach();
                 
            }

            return "OK";
            
        } else if (strcmp(msg_type, D_COOR) == 0) {
            
            std::cout << "\tReceive D_COOR " << std::endl;

            std::unique_lock<std::mutex> lk(node->mutex_election);

            // received: COOR#name#ip:port
            std::string leader_name(strtok(NULL, "#"));
            std::string heardFrom(strtok(NULL, "#"));
            
            node->updateElectionStatus(E_NONE);
            nodeMember->updateLeader(heardFrom, leader_name); // this one displays last leader left
            node->m_queue->resetSequence();
            node->resetSeq();
            
            std::cout << "\tD_COOR Done" << std::endl;
                        
            return "OK";
            
        } else {

#ifdef DEBUGLOG
            std::cout << "\tReceive Unexpected: " << recv_msg << std::endl;
#endif

        }

    }

    return "";
}