bool Array::more(CObjRef v2) const { if (m_px == nullptr || v2.get() == nullptr) { return HPHP::more(toBoolean(), v2.toBoolean()); } check_collection_compare(v2.get()); return false; }
bool Object::equal(CObjRef v2) const { if (m_px == v2.get()) return true; if (!m_px || !v2.get()) return false; if (isResource() || v2.isResource()) return false; return (v2.get()->o_isClass(m_px->o_getClassName()) && toArray().equal(v2.toArray())); }
Object c_SetResultToRefWaitHandle::ti_create(CObjRef wait_handle, VRefParam ref) { TypedValue* var_or_cell = ref->asTypedValue(); if (wait_handle.isNull()) { tvSetNull(*var_or_cell); return wait_handle; } if (!wait_handle.get()->getAttribute(ObjectData::IsWaitHandle)) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected wait_handle to be an instance of WaitHandle or null")); throw e; } auto wh = static_cast<c_WaitHandle*>(wait_handle.get()); // succeeded? set result to ref and give back succeeded wait handle if (wh->isSucceeded()) { tvSet(wh->getResult(), *var_or_cell); return wh; } // failed? reset ref and give back failed wait handle if (wh->isFailed()) { tvSetNull(*var_or_cell); return wh; } // it's still running so it must be WaitableWaitHandle auto child = static_cast<c_WaitableWaitHandle*>(wh); // import child into the current context, detect cross-context cycles auto session = AsioSession::Get(); if (session->isInContext()) { child->enterContext(session->getCurrentContextIdx()); } // make sure the reference is properly boxed so that we can store cell pointer if (UNLIKELY(var_or_cell->m_type != KindOfRef)) { tvBox(var_or_cell); } p_SetResultToRefWaitHandle my_wh = NEWOBJ(c_SetResultToRefWaitHandle)(); my_wh->initialize(child, var_or_cell->m_data.pref); if (UNLIKELY(session->hasOnSetResultToRefCreateCallback())) { session->onSetResultToRefCreate(my_wh.get(), child); } return my_wh; }
void VariableSerializer::write(CObjRef v) { if (!v.isNull() && m_type == JSON) { if (incNestedLevel(v.get(), true)) { writeOverflow(v.get(), true); } else { Array props(ArrayData::Create()); ClassInfo::GetArray(v.get(), v->o_getClassPropTable(), props, true); setObjectInfo(v->o_getClassName(), v->o_getId()); props.serialize(this); } decNestedLevel(v.get()); } else { v.serialize(this); } }
bool Object::equal(CObjRef v2) const { if (m_px == v2.get()) { return true; } if (!m_px || !v2.get()) { return false; } if (v2.get()->getVMClass() != m_px->getVMClass()) { return false; } if (m_px->isCollection()) { return collectionEquals(m_px, v2.get()); } return toArray().equal(v2.toArray()); }
bool Object::equal(CObjRef v2) const { if (m_px == v2.get()) { check_collection_compare(m_px); return true; } if (!m_px || !v2.get()) { return false; } check_collection_compare(m_px, v2.get()); if (isResource() || v2.isResource()) { return false; } return (v2.get()->o_isClass(m_px->o_getClassName()) && toArray().equal(v2.toArray())); }
Variant MethodStatement:: invokeInstanceDirect(CObjRef obj, VariableEnvironment &env, const FunctionCallExpression *caller) const { if (getModifiers() & ClassStatement::Static) { return invokeStaticDirect(obj->o_getClassName(), env, caller); } attemptAccess(FrameInjection::GetClassName(false)); DECLARE_THREAD_INFO RECURSION_INJECTION REQUEST_TIMEOUT_INJECTION #ifdef HOTPROFILER ProfilerInjection pi(info, m_fullName.c_str()); #endif MethScopeVariableEnvironment fenv(this, 0); directBind(env, caller, fenv); fenv.setCurrentObject(obj); String clsName(m_class->name().c_str(), m_class->name().size(), AttachLiteral); EvalFrameInjection fi(clsName, m_fullName.c_str(), fenv, loc()->file, obj.get()); if (m_ref) { return ref(evalBody(fenv)); } return evalBody(fenv); }
void c_ContinuationWaitHandle::markAsFailed(CObjRef exception) { AsioSession::Get()->onFailed(exception); setException(exception.get()); m_continuation = nullptr; m_child = nullptr; }
void throw_exception(CObjRef e) { if (!e.instanceof(SystemLib::s_ExceptionClass)) { raise_error("Exceptions must be valid objects derived from the " "Exception base class"); } DEBUGGER_ATTACHED_ONLY(phpDebuggerExceptionThrownHook(e.get())); throw e; }
Object c_SetResultToRefWaitHandle::ti_create(CObjRef wait_handle, VRefParam ref) { TypedValue* var_or_cell = ref->asTypedValue(); if (wait_handle.isNull()) { tvSet(make_tv<KindOfNull>(), *var_or_cell); return wait_handle; } if (!wait_handle.get()->instanceof(c_WaitHandle::classof())) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected wait_handle to be an instance of WaitHandle or null")); throw e; } c_WaitHandle* wh = static_cast<c_WaitHandle*>(wait_handle.get()); // succeeded? set result to ref and give back succeeded wait handle if (wh->isSucceeded()) { tvSet(wh->getResult(), *var_or_cell); return wh; } // failed? reset ref and give back failed wait handle if (wh->isFailed()) { tvSet(make_tv<KindOfNull>(), *var_or_cell); return wh; } // it's still running so it must be WaitableWaitHandle c_WaitableWaitHandle* child_wh = static_cast<c_WaitableWaitHandle*>(wh); // make sure the reference is properly boxed so that we can store cell pointer if (UNLIKELY(var_or_cell->m_type != KindOfRef)) { tvBox(var_or_cell); } p_SetResultToRefWaitHandle my_wh = NEWOBJ(c_SetResultToRefWaitHandle)(); my_wh->initialize(child_wh, var_or_cell->m_data.pref); AsioSession* session = AsioSession::Get(); if (UNLIKELY(session->hasOnSetResultToRefCreateCallback())) { session->onSetResultToRefCreate(my_wh.get(), child_wh); } return my_wh; }
Object c_StaticExceptionWaitHandle::ti_create(CObjRef exception) { if (!exception.instanceof(SystemLib::s_ExceptionClass)) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected exception to be an instance of Exception")); throw e; } return Create(exception.get()); }
bool same(CVarRef v1, CObjRef v2) { bool null1 = v1.isNull(); bool null2 = v2.isNull(); if (null1 && null2) return true; if (null1 || null2) return false; if (!v1.isObject()) return false; auto const od = v1.getObjectData(); return od == v2.get(); }
void c_SetResultToRefWaitHandle::markAsFailed(CObjRef exception) { RefData* ref = m_ref; m_ref = nullptr; tvSetIgnoreRef(make_tv<KindOfNull>(), *ref->tv()); decRefRef(ref); setException(exception.get()); m_child = nullptr; }
void c_ContinuationWaitHandle::markAsFailed(CObjRef exception) { AsioSession* session = AsioSession::Get(); session->onFailed(exception); if (UNLIKELY(session->hasOnContinuationFailCallback())) { session->onContinuationFail(this, exception); } setException(exception.get()); m_continuation = nullptr; m_child = nullptr; }
bool String::more(CObjRef v2) const { if (m_px == NULL || v2.get() == NULL) { return HPHP::more(toBoolean(), v2.toBoolean()); } if (v2.isResource()) return false; try { return more(v2.toString()); } catch (BadTypeConversionException &e) { return false; } }
void AsioSession::SetOnFailedCallback(CObjRef on_failed_cb) { if (!on_failed_cb.isNull()) { on_failed_cb->incRefCount(); } if (s_on_failed_cb.get()) { decRefObj(s_on_failed_cb.get()); } s_on_failed_cb.set(on_failed_cb.get()); }
Object c_StaticExceptionWaitHandle::ti_create(const char* cls, CObjRef exception) { if (!exception.instanceof("Exception")) { STATIC_METHOD_INJECTION_BUILTIN(StaticExceptionWaitHandle, StaticExceptionWaitHandle::create); Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected exception to be an instance of Exception")); throw e; } p_StaticExceptionWaitHandle wh = NEWOBJ(c_StaticExceptionWaitHandle)(); tvWriteObject(exception.get(), &wh->m_resultOrException); return wh; }
String f_spl_object_hash(CObjRef obj) { if (!s_inited) { Lock lock(s_mutex); if (!s_inited) { f_mt_srand(); s_hash_mask_handle |= f_mt_rand(); s_hash_mask_handle <<= 16; s_hash_mask_handle |= f_mt_rand(); s_hash_mask_handle <<= 16; s_hash_mask_handle |= f_mt_rand(); s_hash_mask_handle <<= 16; s_hash_mask_handle |= f_mt_rand(); s_inited = true; } } char buf[33]; snprintf(buf, sizeof(buf), "%032llx", s_hash_mask_handle ^ (int64)obj.get()); return String(buf, CopyString); }
void f_hphp_unpack_continuation(CObjRef continuation) { if (hhvm) { throw_fatal("hphp_unpack_continuation is not supported under hhvm"); } if (UNLIKELY(!continuation->o_instanceof("GenericContinuation"))) { throw_fatal( "Cannot call hphp_unpack_continuation with a " "non-GenericContinuation object"); } Eval::VariableEnvironment *env = FrameInjection::GetVariableEnvironment(true); if (UNLIKELY(!env)) { throw_fatal("Invalid call hphp_unpack_continuation"); } p_GenericContinuation c( static_cast<c_GenericContinuation*>(continuation.get())); extract(env, c->t_getvars(), 256 /* EXTR_REFS */); }
Variant MethodStatement::invokeInstance(CObjRef obj, CArrRef params, bool check /* = true */) const { if (getModifiers() & ClassStatement::Static) { return invokeStatic(obj->o_getClassName(), params); } if (check) attemptAccess(FrameInjection::GetClassName(false)); // The debug frame should have been pushed at ObjectMethodExpression DECLARE_THREAD_INFO_NOINIT MethScopeVariableEnvironment env(this); env.setCurrentObject(obj); String clsName(m_class->name()); EvalFrameInjection fi(clsName, m_fullName.c_str(), env, loc()->file, obj.get()); if (m_ref) { return ref(invokeImpl(env, params)); } return invokeImpl(env, params); }
Variant MethodStatement::invokeInstance(CObjRef obj, CArrRef params, const MethodStatementWrapper *msw, bool check /* = true */) const { ASSERT(msw->m_methodStatement == this); if (getModifiers() & ClassStatement::Static) { return invokeStatic(obj->o_getClassName(), params, msw, check); } if (check) attemptAccess(FrameInjection::GetClassName(false), msw); // The debug frame should have been pushed at ObjectMethodExpression DECLARE_THREAD_INFO_NOINIT MethScopeVariableEnvironment env(this); env.setCurrentObject(obj); env.setCurrentAlias(get_current_alias()); EvalFrameInjection fi(msw->m_className, m_fullName->data(), env, loc()->file, obj.get(), FrameInjection::ObjectMethod); if (m_ref) { return strongBind(invokeImpl(env, params)); } return invokeImpl(env, params); }
Variant MethodStatement:: invokeInstanceDirect(CObjRef obj, VariableEnvironment &env, const FunctionCallExpression *caller) const { if (getModifiers() & ClassStatement::Static) { return invokeStaticDirect(obj->o_getClassName(), env, caller); } attemptAccess(FrameInjection::GetClassName(false)); DECLARE_THREAD_INFO_NOINIT MethScopeVariableEnvironment fenv(this); directBind(env, caller, fenv); fenv.setCurrentObject(obj); String clsName(m_class->name()); EvalFrameInjection fi(clsName, m_fullName.c_str(), fenv, loc()->file, obj.get()); if (m_ref) { return ref(evalBody(fenv)); } return evalBody(fenv); }
void f_hphp_pack_continuation(CObjRef continuation, int64 label, CVarRef value) { if (hhvm) { throw_fatal("hphp_pack_continuation is not supported under hhvm"); } if (UNLIKELY(!continuation->o_instanceof("GenericContinuation"))) { throw_fatal( "Cannot call hphp_pack_continuation with a " "non-GenericContinuation object"); } Array definedVariables; Eval::VariableEnvironment *env = FrameInjection::GetVariableEnvironment(true); if (UNLIKELY(!env)) { throw_fatal("Invalid call hphp_pack_continuation"); } definedVariables = env->getDefinedVariables(); p_GenericContinuation c( static_cast<c_GenericContinuation*>(continuation.get())); c->t_update(label, value, definedVariables); }
Variant MethodStatement::invokeInstance(CObjRef obj, CArrRef params, bool check /* = true */) const { if (getModifiers() & ClassStatement::Static) { return invokeStatic(obj->o_getClassName(), params); } if (check) attemptAccess(FrameInjection::GetClassName(false)); // The debug frame should have been pushed at ObjectMethodExpression DECLARE_THREAD_INFO RECURSION_INJECTION REQUEST_TIMEOUT_INJECTION #ifdef HOTPROFILER ProfilerInjection pi(info, m_fullName.c_str()); #endif MethScopeVariableEnvironment env(this, params.size()); env.setCurrentObject(obj); EvalFrameInjection fi(m_class->name().c_str(), m_fullName.c_str(), env, loc()->file, obj.get()); if (m_ref) { return ref(invokeImpl(env, params)); } return invokeImpl(env, params); }
Object c_ContinuationWaitHandle::ti_start(const char* cls, CObjRef continuation) { AsioSession* session = AsioSession::Get(); if (UNLIKELY(!continuation.instanceof(SystemLib::s_ContinuationClass))) { Object e(SystemLib::AllocInvalidArgumentExceptionObject( "Expected continuation to be an instance of Continuation")); throw e; } uint16_t depth = session->getCurrentWaitHandleDepth(); if (UNLIKELY(depth >= MAX_DEPTH)) { Object e(SystemLib::AllocInvalidOperationExceptionObject( "Asio stack overflow")); throw e; } c_Continuation* cont = static_cast<c_Continuation*>(continuation.get()); if (!cont->m_waitHandle.isNull()) { if (session->isInContext()) { // throws if cross-context cycle found cont->m_waitHandle->enterContext(session->getCurrentContextIdx()); } return cont->m_waitHandle; } if (UNLIKELY(cont->m_index != -1)) { assert(cont->m_running); Object e(SystemLib::AllocInvalidOperationExceptionObject( "Encountered an attempt to start currently running continuation")); throw e; } p_ContinuationWaitHandle wh = NEWOBJ(c_ContinuationWaitHandle)(); wh->start(cont, depth + 1); if (UNLIKELY(session->hasOnStartedCallback())) { session->onStarted(wh); } return wh; }
Variant MethodStatement:: invokeInstanceDirect(CObjRef obj, CStrRef alias, VariableEnvironment &env, const FunctionCallExpression *caller, const MethodStatementWrapper *msw, bool check /* = true */) const { ASSERT(msw->m_methodStatement == this); if (getModifiers() & ClassStatement::Static) { return invokeStaticDirect(obj->o_getClassName(), alias, env, caller, false, msw, check); } if (check) attemptAccess(FrameInjection::GetClassName(false), msw); DECLARE_THREAD_INFO_NOINIT MethScopeVariableEnvironment fenv(this); directBind(env, caller, fenv); fenv.setCurrentObject(obj); fenv.setCurrentAlias(alias); EvalFrameInjection::EvalStaticClassNameHelper helper(obj); EvalFrameInjection fi(msw->m_className, m_fullName->data(), fenv, loc()->file, obj.get(), FrameInjection::ObjectMethod); if (m_ref) { return strongBind(evalBody(fenv)); } return evalBody(fenv); }
bool Object::more(CObjRef v2) const { check_collection_compare(m_px, v2.get()); return m_px != v2.m_px && toArray().more(v2.toArray()); }
bool Array::more(CObjRef v2) const { if (m_px == NULL || v2.get() == NULL) { return HPHP::more(toBoolean(), v2.toBoolean()); } return true; }
bool Array::less(CObjRef v2) const { if (m_px == NULL || v2.get() == NULL) { return HPHP::less(toBoolean(), v2.toBoolean()); } return false; }
int64_t f_hphp_object_pointer(CObjRef obj) { return (int64_t)obj.get();}