Variant ObjectMethodExpression::eval(VariableEnvironment &env) const { String name(m_name->get(env)); Variant obj(m_obj->eval(env)); if (!obj.is(KindOfObject)) { raise_error("Call to a member function %s() on a non-object", name.c_str()); } EvalFrameInjection::EvalStaticClassNameHelper helper(obj.toObject()); Variant cobj(env.currentObject()); const MethodStatement *ms = NULL; if (cobj.is(KindOfObject) && obj.getObjectData() == cobj.getObjectData()) { // Have to try current class first for private method const ClassStatement *cls = env.currentClassStatement(); if (cls) { const MethodStatement *ccms = cls->findMethod(name.c_str()); if (ccms && ccms->getModifiers() & ClassStatement::Private) { ms = ccms; } } } if (!ms) { ms = obj.getObjectData()->getMethodStatement(name.data()); } SET_LINE; if (ms) { return ref(ms->invokeInstanceDirect(toObject(obj), env, this)); } return ref(obj.getObjectData()->o_invoke_from_eval(name.data(), env, this, m_name->hash(), true)); }
Variant ObjectMethodExpression::eval(VariableEnvironment &env) const { String name(m_name->get(env)); Variant obj(m_obj->eval(env)); if (!obj.is(KindOfObject)) { raise_error("Call to a member function %s() on a non-object", name.c_str()); } #ifdef ENABLE_LATE_STATIC_BINDING EvalFrameInjection::EvalStaticClassNameHelper helper(obj.toObject()); #endif Variant cobj(env.currentObject()); const MethodStatement *ms = NULL; if (cobj.is(KindOfObject) && obj.getObjectData() == cobj.getObjectData()) { // Have to try current class first for private method const ClassStatement *cls = env.currentClassStatement(); if (cls) { const MethodStatement *ccms = cls->findMethod(name.c_str()); if (ccms && ccms->getModifiers() & ClassStatement::Private) { ms = ccms; } } } if (!ms) { ms = obj.getObjectData()->getMethodStatement(name.data()); } SET_LINE; if (ms) { return strongBind(ms->invokeInstanceDirect(toObject(obj), env, this)); } // Handle builtins MethodCallPackage mcp1; mcp1.methodCall(obj, name, -1); const CallInfo* ci = mcp1.ci; // If the lookup failed methodCall() must throw an exception, // so if we reach here ci must not be NULL ASSERT(ci); unsigned int count = m_params.size(); if (count <= 6) { CVarRef a0 = (count > 0) ? evalParam(env, ci, 0) : null; CVarRef a1 = (count > 1) ? evalParam(env, ci, 1) : null; CVarRef a2 = (count > 2) ? evalParam(env, ci, 2) : null; CVarRef a3 = (count > 3) ? evalParam(env, ci, 3) : null; CVarRef a4 = (count > 4) ? evalParam(env, ci, 4) : null; CVarRef a5 = (count > 5) ? evalParam(env, ci, 5) : null; return strongBind((ci->getMethFewArgs())(mcp1, count, a0, a1, a2, a3, a4, a5)); } if (RuntimeOption::UseArgArray) { ArgArray *args = prepareArgArray(env, ci, count); return strongBind((ci->getMeth())(mcp1, args)); } ArrayInit ai(count); for (unsigned int i = 0; i < count; ++i) { if (ci->mustBeRef(i)) { ai.setRef(m_params[i]->refval(env)); } else if (ci->isRef(i)) { ai.setRef(m_params[i]->refval(env, 0)); } else { ai.set(m_params[i]->eval(env)); } } return strongBind((ci->getMeth())(mcp1, Array(ai.create()))); }