void UnitEmitter::addPreClassEmitter(PreClassEmitter* pce) { if (pce->hoistability() && m_hoistablePreClassSet.count(pce->name())) { pce->setHoistable(PreClass::Mergeable); } auto hoistable = pce->hoistability(); if (hoistable >= PreClass::MaybeHoistable) { m_hoistablePreClassSet.insert(pce->name()); if (hoistable == PreClass::ClosureHoistable) { // Closures should appear at the VERY top of the file, so if any class in // the same file tries to use them, they are already defined. We had a // fun race where one thread was autoloading a file, finished parsing the // class, then another thread came along and saw the class was already // loaded and ran it before the first thread had time to parse the // closure class. m_hoistablePceIdList.push_front(pce->id()); } else { m_hoistablePceIdList.push_back(pce->id()); } } else { m_allClassesHoistable = false; } if (hoistable >= PreClass::Mergeable && hoistable < PreClass::AlwaysHoistable) { if (m_returnSeen) { m_allClassesHoistable = false; } else { pushMergeableClass(pce); } } }
void UnitEmitter::addPreClassEmitter(PreClassEmitter* pce) { if (pce->hoistability() && m_hoistablePreClassSet.count(pce->name())) { pce->setHoistable(PreClass::Mergeable); } auto hoistable = pce->hoistability(); if (hoistable >= PreClass::MaybeHoistable) { m_hoistablePreClassSet.insert(pce->name()); m_hoistablePceIdList.push_back(pce->id()); } else { m_allClassesHoistable = false; } if (hoistable >= PreClass::Mergeable && hoistable < PreClass::AlwaysHoistable) { if (m_returnSeen) { m_allClassesHoistable = false; } else { pushMergeableClass(pce); } } }
PreClassEmitter* UnitEmitter::newPreClassEmitter( const StringData* name, PreClass::Hoistable hoistable ) { if (hoistable && m_hoistablePreClassSet.count(name)) { hoistable = PreClass::Mergeable; } PreClassEmitter* pce = new PreClassEmitter(*this, m_pceVec.size(), name, hoistable); if (hoistable >= PreClass::MaybeHoistable) { m_hoistablePreClassSet.insert(name); if (hoistable == PreClass::ClosureHoistable) { // Closures should appear at the VERY top of the file, so if any class in // the same file tries to use them, they are already defined. We had a // fun race where one thread was autoloading a file, finished parsing the // class, then another thread came along and saw the class was already // loaded and ran it before the first thread had time to parse the // closure class. m_hoistablePceIdList.push_front(pce->id()); } else { m_hoistablePceIdList.push_back(pce->id()); } } else { m_allClassesHoistable = false; } if (hoistable >= PreClass::Mergeable && hoistable < PreClass::AlwaysHoistable) { if (m_returnSeen) { m_allClassesHoistable = false; } else { pushMergeableClass(pce); } } m_pceVec.push_back(pce); return pce; }