/*
 * 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 "mirror/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(mirror::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<mirror::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<mirror::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_
