void AMXStackFramePrinter::PrintArgumentList(const AMXStackFrame &frame) {
  AMXStackFrame prev_frame = frame.GetPrevious();

  if (prev_frame) {
    // Although the symbol's code start address points at the state
    // switch code block, function arguments actually use the real
    // function address for the code start because in different states
    // they may be not the same.
    cell arg_address = frame.caller_address();
    if (UsesAutomata(frame)) {
      arg_address = GetRealFunctionAddress(frame.amx(), frame.caller_address(),
                                                        frame.return_address());
    }

    std::vector<AMXDebugSymbol> args;
    int num_actual_args = 0;

    if (HaveDebugInfo()) {
      std::remove_copy_if(debug_info_->GetSymbols().begin(),
                          debug_info_->GetSymbols().end(),
                          std::back_inserter(args),
                          std::not1(IsArgumentOf(arg_address)));
      std::sort(args.begin(), args.end());
      num_actual_args = static_cast<int>(args.size());
    } else {
      static const int kMaxRawArgs = 10;
      num_actual_args = std::min(kMaxRawArgs,
                                 GetNumArgs(frame.amx(), prev_frame.address()));
    }

    // Print a comma-separated list of arguments and their values.
    // If debug info is not available argument names are omitted,
    // so only the values are printed.
    for (int i = 0; i < num_actual_args; i++) {
      if (i > 0) {
        *stream_ << ", ";
      }
      if (HaveDebugInfo()) {
        PrintArgument(prev_frame, args[i], i);
      } else {
        PrintArgument(prev_frame, i);
      }
    }

    // If the number of actual arguments passed to the function exceeds
    // that obtained via debug info the function may take a variable
    // number of arguments. In this case we don't evaluate them but just
    // just say that they are present as we can't say anything about
    // their names and types.
    int num_var_args = GetNumArgs(frame.amx(), prev_frame.address())
                     - num_actual_args;
    if (num_var_args > 0) {
      if (num_actual_args != 0) {
        *stream_ << ", ";
      }
      PrintVariableArguments(num_var_args);
    }
  }
}
Example #2
0
ArgDef ArgSet::GetArg (int index) const
{
  assert (index >= 0);
  assert (index < GetNumArgs());

  return _args[index];
}