diff --git a/hphp/runtime/ext/asio/gen_array_wait_handle.cpp b/hphp/runtime/ext/asio/gen_array_wait_handle.cpp index bf950403d..495bf2f71 100644 --- a/hphp/runtime/ext/asio/gen_array_wait_handle.cpp +++ b/hphp/runtime/ext/asio/gen_array_wait_handle.cpp @@ -34,12 +34,6 @@ namespace { exception_field = new_exception; } } - - void putInvalidArgumentException(Object& exception_field) { - Object e(SystemLib::AllocInvalidArgumentExceptionObject( - "Expected dependencies to be an array of WaitHandle instances")); - putException(exception_field, e.get()); - } } c_GenArrayWaitHandle::c_GenArrayWaitHandle(VM::Class* cb) @@ -57,7 +51,6 @@ void c_GenArrayWaitHandle::t___construct() { Object c_GenArrayWaitHandle::ti_create(const char* cls, CArrRef dependencies) { Array deps = dependencies->copy(); - Object exception; for (ssize_t iter_pos = deps->iter_begin(); iter_pos != ArrayData::invalid_index; iter_pos = deps->iter_advance(iter_pos)) { @@ -67,22 +60,37 @@ Object c_GenArrayWaitHandle::ti_create(const char* cls, CArrRef dependencies) { 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; } - c_WaitHandle* child = c_WaitHandle::fromTypedValue(current); - if (UNLIKELY(!child)) { - putInvalidArgumentException(exception); - } else if (child->isSucceeded()) { + assert(current->m_type == KindOfObject); + assert(dynamic_cast(current->m_data.pobj)); + auto child = static_cast(current->m_data.pobj); + + if (child->isSucceeded()) { tvSetIgnoreRef(child->getResult(), current); } else if (child->isFailed()) { putException(exception, child->getException()); } else { - c_WaitableWaitHandle* child_wh = - static_cast(child); + assert(dynamic_cast(child)); + auto child_wh = static_cast(child); c_GenArrayWaitHandle* my_wh = NEWOBJ(c_GenArrayWaitHandle)(); my_wh->initialize(exception, deps, iter_pos, child_wh); @@ -116,26 +124,23 @@ void c_GenArrayWaitHandle::onUnblocked() { m_iterPos = m_deps->iter_advance(m_iterPos)) { TypedValue* current = m_deps->nvGetValueRef(m_iterPos); - if (UNLIKELY(current->m_type == KindOfRef)) { - tvUnbox(current); - } - if (IS_NULL_TYPE(current->m_type)) { // {uninit,null} yields null tvWriteNull(current); continue; } - c_WaitHandle* child = c_WaitHandle::fromTypedValue(current); - if (UNLIKELY(!child)) { - putInvalidArgumentException(m_exception); - } else if (child->isSucceeded()) { + assert(current->m_type == KindOfObject); + assert(dynamic_cast(current->m_data.pobj)); + auto child = static_cast(current->m_data.pobj); + + if (child->isSucceeded()) { tvSetIgnoreRef(child->getResult(), current); } else if (child->isFailed()) { putException(m_exception, child->getException()); } else { - c_WaitableWaitHandle* child_wh = - static_cast(child); + assert(dynamic_cast(child)); + auto child_wh = static_cast(child); try { blockOn(child_wh);