// Copyright 2011 Google Inc. All Rights Reserved.

#include "jni_internal.h"

#include <algorithm>

#include "assembler.h"
#include "object.h"

#define __ assembler->

namespace art {

// Creates a function which invokes a managed method with an array of
// arguments.
//
// At the time of call, the environment looks something like this:
//
// R0 = method pointer
// R1 = receiver pointer or NULL for static methods
// R2 = (managed) thread pointer
// R3 = argument array or NULL for no argument methods
// [SP] = JValue* result or NULL for void returns
//
// As the JNI call has already transitioned the thread into the
// "running" state the remaining responsibilities of this routine are
// to save the native register value and restore the managed thread
// register and transfer arguments from the array into register and on
// the stack, if needed.  On return, the thread register must be
// shuffled and the return value must be store into the result JValue.
void CreateInvokeStub(Assembler* assembler, Method* method) {
  // Size of frame - spill of R9/LR + Method* + possible receiver + arg array
  size_t unpadded_frame_size = (3 * kPointerSize) +
                               (method->IsStatic() ? 0 : kPointerSize) +
                               method->NumArgArrayBytes();
  size_t frame_size = RoundUp(unpadded_frame_size, kStackAlignment);

  // Spill R9 and LR
  RegList save = (1 << R9);
  __ PushList(save | (1 << LR));

  // Move the managed thread pointer into R9.
  __ mov(R9, ShifterOperand(R2));

  // Move frame down for arguments less 2 pushed values above
  __ AddConstant(SP, -frame_size + (2 * kPointerSize));

  // Can either get 3 or 2 arguments into registers
  size_t reg_bytes = (method->IsStatic() ? 3 : 2) * kPointerSize;
  // Bytes passed by stack
  size_t stack_bytes;
  if (method->NumArgArrayBytes() > reg_bytes) {
    stack_bytes = method->NumArgArrayBytes() - reg_bytes;
  } else {
    stack_bytes = 0;
    reg_bytes = method->NumArgArrayBytes();
  }

  // Method* at bottom of frame is null thereby terminating managed stack crawls
  __ LoadImmediate(IP, 0, AL);
  __ StoreToOffset(kStoreWord, IP, SP, 0);

  // Copy values by stack
  for (size_t off = 0; off < stack_bytes; off += kPointerSize) {
    // we're displaced off of r3 by bytes that'll go in registers
    int r3_offset = reg_bytes + off;
    __ LoadFromOffset(kLoadWord, IP, R3, r3_offset);

    // we're displaced off of the arguments by the spill space for the incoming
    // arguments and the Method*
    int sp_offset = reg_bytes + kPointerSize + off;
    __ StoreToOffset(kStoreWord, IP, SP, sp_offset);
  }

  // Move all the register arguments into place.
  if (method->IsStatic()) {
    if (reg_bytes > 0) {
      __ LoadFromOffset(kLoadWord, R1, R3, 0);
      if (reg_bytes > 4) {
        __ LoadFromOffset(kLoadWord, R2, R3, 4);
        if (reg_bytes > 8) {
          __ LoadFromOffset(kLoadWord, R3, R3, 8);
        }
      }
    }
  } else {
    if (reg_bytes > 0) {
      __ LoadFromOffset(kLoadWord, R2, R3, 0);
      if (reg_bytes > 4) {
        __ LoadFromOffset(kLoadWord, R3, R3, 4);
      }
    }
  }

  // Load the code pointer we are about to call.
  __ LoadFromOffset(kLoadWord, IP, R0, method->GetCodeOffset().Int32Value());

  // Do the call.
  __ blx(IP);

  // If the method returns a value, store it to the result pointer.
  char ch = method->GetShorty()[0];
  if (ch != 'V') {
    // Load the result JValue pointer of the stub caller's out args.
    __ LoadFromOffset(kLoadWord, IP, SP, frame_size);
    if (ch == 'D' || ch == 'J') {
      __ StoreToOffset(kStoreWordPair, R0, IP, 0);
    } else {
      __ StoreToOffset(kStoreWord, R0, IP, 0);
    }
  }

  // Remove the frame less the spilled R9 and LR
  __ AddConstant(SP, frame_size - (2 * kPointerSize));

  // Pop R9 and the LR into PC
  __ PopList(save | (1 << PC));
}

}  // namespace art
