Object c_GenArrayWaitHandle::ti_create(const char* cls, CArrRef dependencies) { Array deps = dependencies->copy(); for (ssize_t iter_pos = deps->iter_begin(); iter_pos != ArrayData::invalid_index; iter_pos = deps->iter_advance(iter_pos)) { TypedValue* current = deps->nvGetValueRef(iter_pos); if (UNLIKELY(current->m_type == KindOfRef)) { tvUnbox(current); } if (!c_WaitHandle::fromTypedValue(current) && !IS_NULL_TYPE(current->m_type)) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected dependencies to be an array of WaitHandle instances")); throw e; } } Object exception; for (ssize_t iter_pos = deps->iter_begin(); iter_pos != ArrayData::invalid_index; iter_pos = deps->iter_advance(iter_pos)) { TypedValue* current = deps->nvGetValueRef(iter_pos); if (IS_NULL_TYPE(current->m_type)) { // {uninit,null} yields null tvWriteNull(current); continue; } assert(current->m_type == KindOfObject); assert(dynamic_cast<c_WaitHandle*>(current->m_data.pobj)); auto child = static_cast<c_WaitHandle*>(current->m_data.pobj); if (child->isSucceeded()) { tvSetIgnoreRef(child->getResult(), current); } else if (child->isFailed()) { putException(exception, child->getException()); } else { assert(dynamic_cast<c_WaitableWaitHandle*>(child)); auto child_wh = static_cast<c_WaitableWaitHandle*>(child); c_GenArrayWaitHandle* my_wh = NEWOBJ(c_GenArrayWaitHandle)(); my_wh->initialize(exception, deps, iter_pos, child_wh); return my_wh; } } if (exception.isNull()) { TypedValue tv; tv.m_type = KindOfArray; tv.m_data.parr = deps.get(); return c_StaticResultWaitHandle::Create(&tv); } else { return c_StaticExceptionWaitHandle::Create(exception.get()); } }