/// 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(); }
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; }
/// 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; }
/** * 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 }
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()); } }
/// 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); }
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); }
/// 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); }
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; }
/// 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); }
// 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); } }
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; } } }
/// 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); }
/// 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); }
// 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); } }
/** * 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; }
/// 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; }
/// 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; }
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; }
/** * 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; }
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()); }
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); }
/// 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); } } }
/// 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); } } }
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 ""; }