/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_SRC_INVOKE_ARG_ARRAY_BUILDER_H_
#define ART_SRC_INVOKE_ARG_ARRAY_BUILDER_H_

#include "object.h"
#include "scoped_thread_state_change.h"

namespace art {

static inline size_t NumArgArrayBytes(const char* shorty, uint32_t shorty_len) {
  size_t num_bytes = 0;
  for (size_t i = 1; i < shorty_len; ++i) {
    char ch = shorty[i];
    if (ch == 'D' || ch == 'J') {
      num_bytes += 8;
    } else if (ch == 'L') {
      // Argument is a reference or an array.  The shorty descriptor
      // does not distinguish between these types.
      num_bytes += sizeof(Object*);
    } else {
      num_bytes += 4;
    }
  }
  return num_bytes;
}

class ArgArray {
 public:
  explicit ArgArray(const char* shorty, uint32_t shorty_len)
      : shorty_(shorty), shorty_len_(shorty_len) {
    if (shorty_len - 1 < kSmallArgArraySize) {
      arg_array_ = small_arg_array_;
    } else {
      large_arg_array_.reset(new JValue[shorty_len_ - 1]);
      arg_array_ = large_arg_array_.get();
    }
  }

  JValue* get() {
    return arg_array_;
  }

  void BuildArgArray(const ScopedObjectAccess& soa, va_list ap)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[offset].SetZ(va_arg(ap, jint));
          break;
        case 'B':
          arg_array_[offset].SetB(va_arg(ap, jint));
          break;
        case 'C':
          arg_array_[offset].SetC(va_arg(ap, jint));
          break;
        case 'S':
          arg_array_[offset].SetS(va_arg(ap, jint));
          break;
        case 'I':
          arg_array_[offset].SetI(va_arg(ap, jint));
          break;
        case 'F':
          arg_array_[offset].SetF(va_arg(ap, jdouble));
          break;
        case 'L':
          arg_array_[offset].SetL(soa.Decode<Object*>(va_arg(ap, jobject)));
          break;
        case 'D':
          arg_array_[offset].SetD(va_arg(ap, jdouble));
          break;
        case 'J':
          arg_array_[offset].SetJ(va_arg(ap, jlong));
          break;
      }
    }
  }

  void BuildArgArray(const ScopedObjectAccess& soa, jvalue* args)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[offset].SetZ(args[offset].z);
          break;
        case 'B':
          arg_array_[offset].SetB(args[offset].b);
          break;
        case 'C':
          arg_array_[offset].SetC(args[offset].c);
          break;
        case 'S':
          arg_array_[offset].SetS(args[offset].s);
          break;
        case 'I':
          arg_array_[offset].SetI(args[offset].i);
          break;
        case 'F':
          arg_array_[offset].SetF(args[offset].f);
          break;
        case 'L':
          arg_array_[offset].SetL(soa.Decode<Object*>(args[offset].l));
          break;
        case 'D':
          arg_array_[offset].SetD(args[offset].d);
          break;
        case 'J':
          arg_array_[offset].SetJ(args[offset].j);
          break;
      }
    }
  }

  void BuildArgArray(const ShadowFrame& shadow_frame, uint32_t range_start)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[i - 1].SetZ(shadow_frame.GetVReg(range_start + offset));
          break;
        case 'B':
          arg_array_[i - 1].SetB(shadow_frame.GetVReg(range_start + offset));
          break;
        case 'C':
          arg_array_[i - 1].SetC(shadow_frame.GetVReg(range_start + offset));
          break;
        case 'S':
          arg_array_[i - 1].SetS(shadow_frame.GetVReg(range_start + offset));
          break;
        case 'I':
          arg_array_[i - 1].SetI(shadow_frame.GetVReg(range_start + offset));
          break;
        case 'F':
          arg_array_[i - 1].SetF(shadow_frame.GetVRegFloat(range_start + offset));
          break;
        case 'L':
          arg_array_[i - 1].SetL(shadow_frame.GetVRegReference(range_start + offset));
          break;
        case 'D':
          arg_array_[i - 1].SetD(shadow_frame.GetVRegDouble(range_start + offset));
          offset++;
          break;
        case 'J':
          arg_array_[i - 1].SetJ(shadow_frame.GetVRegLong(range_start + offset));
          offset++;
          break;
      }
    }
  }

  void BuildArgArray(const ShadowFrame& shadow_frame, const uint32_t* arg_regs)
      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
    for (size_t i = 1, offset = 0; i < shorty_len_; ++i, ++offset) {
      switch (shorty_[i]) {
        case 'Z':
          arg_array_[i - 1].SetZ(shadow_frame.GetVReg(arg_regs[offset]));
          break;
        case 'B':
          arg_array_[i - 1].SetB(shadow_frame.GetVReg(arg_regs[offset]));
          break;
        case 'C':
          arg_array_[i - 1].SetC(shadow_frame.GetVReg(arg_regs[offset]));
          break;
        case 'S':
          arg_array_[i - 1].SetS(shadow_frame.GetVReg(arg_regs[offset]));
          break;
        case 'I':
          arg_array_[i - 1].SetI(shadow_frame.GetVReg(arg_regs[offset]));
          break;
        case 'F':
          arg_array_[i - 1].SetF(shadow_frame.GetVRegFloat(arg_regs[offset]));
          break;
        case 'L':
          arg_array_[i - 1].SetL(shadow_frame.GetVRegReference(arg_regs[offset]));
          break;
        case 'D':
          arg_array_[i - 1].SetD(shadow_frame.GetVRegDouble(arg_regs[offset]));
          offset++;
          break;
        case 'J':
          arg_array_[i - 1].SetJ(shadow_frame.GetVRegLong(arg_regs[offset]));
          offset++;
          break;
      }
    }
  }

 private:
  enum { kSmallArgArraySize = 16 };
  const char* const shorty_;
  const uint32_t shorty_len_;
  JValue* arg_array_;
  JValue small_arg_array_[kSmallArgArraySize];
  UniquePtr<JValue[]> large_arg_array_;
};

}  // namespace art

#endif  // ART_SRC_INVOKE_ARG_ARRAY_BUILDER_H_
