Object ClassStatics::create(CArrRef params, bool init /* = true */, ObjectData* root /* = NULL */) { Object o(createOnly(root)); if (init) { MethodCallPackage mcp; mcp.construct(o); if (mcp.ci) { (mcp.ci->getMeth())(mcp, params); } } return o; }
Variant MethodStatement::MethInvokerFewArgs(MethodCallPackage &mcp, int count, INVOKE_FEW_ARGS_IMPL_ARGS) { const MethodStatementWrapper *msw = (const MethodStatementWrapper*)mcp.extra; const MethodStatement *ms = msw->m_methodStatement; bool check = !ms->m_name->isame(s___invoke.get()); bool isStatic = ms->getModifiers() & ClassStatement::Static; if (isStatic || !mcp.obj) { String cn; if (UNLIKELY(!isStatic && mcp.isObj && mcp.obj == NULL)) { // this is needed for continuations where // we are passed the dummy object cn = ms->getClass()->name(); } else { cn = mcp.getClassName(); } if (ms->refReturn()) { return strongBind(ms->invokeStaticFewArgs(cn, count, INVOKE_FEW_ARGS_PASS_ARGS, msw, check)); } else { return ms->invokeStaticFewArgs(cn, count, INVOKE_FEW_ARGS_PASS_ARGS, msw, check); } } else { if (ms->refReturn()) { return strongBind(ms->invokeInstanceFewArgs(mcp.rootObj, count, INVOKE_FEW_ARGS_PASS_ARGS, msw, check)); } else { return ms->invokeInstanceFewArgs(mcp.rootObj, count, INVOKE_FEW_ARGS_PASS_ARGS, msw, check); } } }
Variant MethodStatement::MethInvoker(MethodCallPackage &mcp, CArrRef params) { const MethodStatement *ms = (const MethodStatement*)mcp.extra; if (ms->getModifiers() & ClassStatement::Static || !mcp.obj) { String cn(mcp.getClassName()); if (ms->refReturn()) { return ref(ms->invokeStatic(cn.c_str(), params)); } else { return ms->invokeStatic(cn.c_str(), params); } } else { if (ms->refReturn()) { return ref(ms->invokeInstance(mcp.rootObj, params)); } else { return ms->invokeInstance(mcp.rootObj, params); } } }
bool f_is_callable(CVarRef v, bool syntax /* = false */, VRefParam name /* = null */) { bool ret = true; if (LIKELY(!syntax)) { if (hhvm) { CallerFrame cf; ObjectData* obj = NULL; HPHP::VM::Class* cls = NULL; StringData* invName = NULL; const HPHP::VM::Func* f = vm_decode_function(v, cf(), false, obj, cls, invName, false); if (f == NULL) { ret = false; } if (invName != NULL) { LITSTR_DECREF(invName); } } else { MethodCallPackage mcp; String classname, methodname; bool doBind; ret = get_user_func_handler(v, true, mcp, classname, methodname, doBind, false); if (ret && mcp.ci->m_flags & (CallInfo::Protected|CallInfo::Private)) { classname = mcp.getClassName(); if (!ClassInfo::HasAccess(classname, *mcp.name, mcp.ci->m_flags & CallInfo::StaticMethod || !mcp.obj, mcp.obj)) { ret = false; } } } if (!name.isReferenced()) return ret; } Variant::TypedValueAccessor tv_func = v.getTypedAccessor(); if (Variant::IsString(tv_func)) { if (name.isReferenced()) name = Variant::GetStringData(tv_func); return ret; } if (Variant::GetAccessorType(tv_func) == KindOfArray) { CArrRef arr = Variant::GetAsArray(tv_func); CVarRef clsname = arr.rvalAtRef(0LL); CVarRef mthname = arr.rvalAtRef(1LL); if (arr.size() != 2 || &clsname == &null_variant || &mthname == &null_variant) { name = v.toString(); return false; } Variant::TypedValueAccessor tv_meth = mthname.getTypedAccessor(); if (!Variant::IsString(tv_meth)) { if (name.isReferenced()) name = v.toString(); return false; } Variant::TypedValueAccessor tv_cls = clsname.getTypedAccessor(); if (Variant::GetAccessorType(tv_cls) == KindOfObject) { name = Variant::GetObjectData(tv_cls)->o_getClassName(); } else if (Variant::IsString(tv_cls)) { name = Variant::GetStringData(tv_cls); } else { name = v.toString(); return false; } name = concat3(name, "::", Variant::GetAsString(tv_meth)); return ret; } if (Variant::GetAccessorType(tv_func) == KindOfObject) { ObjectData *d = Variant::GetObjectData(tv_func); if (hhvm) { static const StringData* sd__invoke = StringData::GetStaticString("__invoke"); const VM::Func* invoke = d->getVMClass()->lookupMethod(sd__invoke); if (name.isReferenced()) { if (d->o_instanceof("closure")) { // Hack to stop the mangled name from showing up name = "Closure::__invoke"; } else { name = d->o_getClassName() + "::__invoke"; } } return invoke != NULL; } else { void *extra; if (d->t___invokeCallInfoHelper(extra)) { name = d->o_getClassName() + "::__invoke"; return ret; } if (name.isReferenced()) { name = v.toString(); } } } return false; }
bool ClassStatics::os_get_call_info(MethodCallPackage &info, int64 hash /* = -1 */) { info.fail(); return false; }