/**
   * Evaluates the expression.
   *
   * @param env the calling environment.
   * @return the expression value.
   */
  @Override
  public Value eval(Env env) {
    Value qThis = env.getThis();

    QuercusClass cls = qThis.getQuercusClass();

    if (cls == null) {
      env.error(L.l("no calling class found"), getLocation());

      return NullValue.NULL;
    }

    StringValue methodName = _methodName.evalStringValue(env);
    int hash = methodName.hashCodeCaseInsensitive();

    Value[] values = evalArgs(env, _args);

    env.pushCall(this, cls, values);

    try {
      env.checkTimeout();

      return cls.callMethod(env, qThis, methodName, hash, values);
    } finally {
      env.popCall();
    }
  }