TypedValue* NameValueTable::lookupAdd(const StringData* name) { auto tv = findTypedValue(name); if (tv->m_type == KindOfUninit) { tvWriteNull(tv); } return tv; }
void c_AwaitAllWaitHandle::markAsFinished() { auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); decRefObj(this); }
NEVER_INLINE TypedValue arrayGetNotFound(const StringData* k) { raise_notice("Undefined index: %s", k->data()); TypedValue v; tvWriteNull(&v); return v; }
NEVER_INLINE TypedValue arrayGetNotFound(int64_t k) { raise_notice("Undefined index: %" PRId64, k); TypedValue v; tvWriteNull(&v); return v; }
TypedValue* NameValueTable::findTypedValue(const StringData* name) { Elm* elm = insert(name); if (elm->m_tv.m_type == KindOfInvalid) { tvWriteNull(&elm->m_tv); return &elm->m_tv; } return derefNamedLocal(&elm->m_tv); }
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()); } }
member_lval GlobalsArray::LvalStr(ArrayData* ad, StringData* k, bool /*copy*/) { auto a = asGlobals(ad); TypedValue* tv = a->m_tab->lookup(k); if (!tv) { TypedValue nulVal; tvWriteNull(nulVal); tv = a->m_tab->set(k, &nulVal); } return member_lval { a, tv }; }
void c_RescheduleWaitHandle::run() { // may happen if scheduled in multiple contexts if (getState() != STATE_SCHEDULED) { return; } setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); done(); }
ArrayData* NameValueTableWrapper::lval(StringData* k, Variant*& ret, bool copy, bool checkExist) { TypedValue* tv = m_tab->lookup(k); if (!tv) { TypedValue nulVal; tvWriteNull(&nulVal); tv = m_tab->set(k, &nulVal); } ret = &tvAsVariant(tv); return this; }
void c_RescheduleWaitHandle::run() { // may happen if scheduled in multiple contexts if (getState() != STATE_SCHEDULED) { return; } auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); }
void c_SleepWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto const parentChain = getFirstParent(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); c_BlockableWaitHandle::UnblockChain(parentChain); }
ArrayData* GlobalsArray::LvalStr(ArrayData* ad, StringData* k, Variant*& ret, bool copy) { auto a = asGlobals(ad); TypedValue* tv = a->m_tab->lookup(k); if (!tv) { TypedValue nulVal; tvWriteNull(&nulVal); tv = a->m_tab->set(k, &nulVal); } ret = &tvAsVariant(tv); return a; }
ArrayData* NameValueTableWrapper::LvalStr(ArrayData* ad, StringData* k, Variant*& ret, bool copy) { auto a = asNVTW(ad); TypedValue* tv = a->m_tab->lookup(k); if (!tv) { TypedValue nulVal; tvWriteNull(&nulVal); tv = a->m_tab->set(k, &nulVal); } ret = &tvAsVariant(tv); return a; }
void c_SleepWaitHandle::process() { assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnSleepSuccess())) { session->onSleepSuccess(this); } }
void c_GenArrayWaitHandle::onUnblocked() { for (; m_iterPos != ArrayData::invalid_index; m_iterPos = m_deps->iter_advance(m_iterPos)) { TypedValue* current = m_deps->nvGetValueRef(m_iterPos); 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(m_exception, child->getException()); } else { assert(dynamic_cast<c_WaitableWaitHandle*>(child)); auto child_wh = static_cast<c_WaitableWaitHandle*>(child); try { blockOn(child_wh); return; } catch (const Object& cycle_exception) { putException(m_exception, cycle_exception.get()); } } } if (m_exception.isNull()) { TypedValue result; result.m_type = KindOfArray; result.m_data.parr = m_deps.get(); setResult(&result); m_deps = nullptr; } else { setException(m_exception.get()); m_exception = nullptr; m_deps = nullptr; } }
ArrayData* StructArray::LvalStr( ArrayData* ad, StringData* property, Variant*& ret, bool copy ) { auto structArray = asStructArray(ad); auto shape = structArray->shape(); auto offset = shape->offsetFor(property); if (offset != PropertyTable::kInvalidOffset) { auto const result = asStructArray( copy ? Copy(structArray) : structArray); ret = &tvAsVariant(&result->data()[offset]); return result; } auto convertToMixedAndAdd = [&]() { auto mixed = copy ? ToMixedCopy(structArray) : ToMixed(structArray); return mixed->addLvalImpl(property, ret); }; // We don't support adding non-static strings yet. StringData* staticKey; if (property->isStatic()) { staticKey = property; } else { staticKey = lookupStaticString(property); if (!staticKey) return convertToMixedAndAdd(); } auto newShape = shape->transition(staticKey); if (!newShape) return convertToMixedAndAdd(); auto result = copy ? CopyAndResizeIfNeeded(structArray, newShape) : ResizeIfNeeded(structArray, newShape); assert(newShape->hasOffsetFor(staticKey)); offset = newShape->offsetFor(staticKey); tvWriteNull(&result->data()[offset]); ret = &tvAsVariant(&result->data()[offset]); return result; }
void c_AwaitAllWaitHandle::onUnblocked() { assert(m_cur >= 0); assert(m_children[m_cur]->isFinished()); auto child = &m_children[m_cur]; do { decRefObj(*child); if (m_cur == 0) { auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); decRefObj(this); return; } --m_cur; --child; } while ((*child)->isFinished()); assert(child == &m_children[m_cur]); blockOnCurrent<true>(); }
bool c_SleepWaitHandle::process() { if (getState() == STATE_FAILED) { // sleep handle was cancelled, everything is taken care of return false; } assert(getState() == STATE_WAITING); if (isInContext()) { unregisterFromContext(); } auto parentChain = getParentChain(); setState(STATE_SUCCEEDED); tvWriteNull(&m_resultOrException); parentChain.unblock(); auto session = AsioSession::Get(); if (UNLIKELY(session->hasOnSleepSuccess())) { session->onSleepSuccess(this); } return true; }