/*
 * Copyright (C) 2016 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_RUNTIME_COMMON_DEX_OPERATIONS_H_
#define ART_RUNTIME_COMMON_DEX_OPERATIONS_H_

#include "android-base/logging.h"
#include "art_field.h"
#include "art_method.h"
#include "base/locks.h"
#include "base/macros.h"
#include "class_linker.h"
#include "dex/code_item_accessors.h"
#include "dex/dex_file_structs.h"
#include "dex/primitive.h"
#include "handle_scope-inl.h"
#include "instrumentation.h"
#include "interpreter/interpreter.h"
#include "interpreter/shadow_frame.h"
#include "interpreter/unstarted_runtime.h"
#include "jvalue-inl.h"
#include "mirror/class.h"
#include "mirror/object.h"
#include "obj_ptr-inl.h"
#include "runtime.h"
#include "stack.h"
#include "thread.h"

namespace art {

namespace interpreter {
  void ArtInterpreterToInterpreterBridge(Thread* self,
                                        const dex::CodeItem* code_item,
                                        ShadowFrame* shadow_frame,
                                        JValue* result)
     REQUIRES_SHARED(Locks::mutator_lock_);

  void ArtInterpreterToCompiledCodeBridge(Thread* self,
                                          ArtMethod* caller,
                                          ShadowFrame* shadow_frame,
                                          uint16_t arg_offset,
                                          JValue* result);
}  // namespace interpreter

inline void PerformCall(Thread* self,
                        const CodeItemDataAccessor& accessor,
                        ArtMethod* caller_method,
                        const size_t first_dest_reg,
                        ShadowFrame* callee_frame,
                        JValue* result,
                        bool use_interpreter_entrypoint)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  if (LIKELY(Runtime::Current()->IsStarted())) {
    if (use_interpreter_entrypoint) {
      interpreter::ArtInterpreterToInterpreterBridge(self, accessor, callee_frame, result);
    } else {
      interpreter::ArtInterpreterToCompiledCodeBridge(
          self, caller_method, callee_frame, first_dest_reg, result);
    }
  } else {
    interpreter::UnstartedRuntime::Invoke(self, accessor, callee_frame, result, first_dest_reg);
  }
}

template <typename T>
inline void DCheckStaticState(Thread* self, T* entity) REQUIRES_SHARED(Locks::mutator_lock_) {
  if (kIsDebugBuild) {
    ObjPtr<mirror::Class> klass = entity->GetDeclaringClass();
    if (entity->IsStatic()) {
      klass->AssertInitializedOrInitializingInThread(self);
    } else {
      CHECK(klass->IsInitializing() || klass->IsErroneousResolved());
    }
  }
}

template<Primitive::Type field_type>
static ALWAYS_INLINE bool DoFieldGetCommon(Thread* self,
                                           const ShadowFrame& shadow_frame,
                                           ObjPtr<mirror::Object> obj,
                                           ArtField* field,
                                           JValue* result)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  DCheckStaticState(self, field);

  // Report this field access to instrumentation if needed.
  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
  if (UNLIKELY(instrumentation->HasFieldReadListeners())) {
    StackHandleScope<1> hs(self);
    // Wrap in handle wrapper in case the listener does thread suspension.
    HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
    ObjPtr<mirror::Object> this_object;
    if (!field->IsStatic()) {
      this_object = obj;
    }
    instrumentation->FieldReadEvent(self,
                                    this_object.Ptr(),
                                    shadow_frame.GetMethod(),
                                    shadow_frame.GetDexPC(),
                                    field);
    if (UNLIKELY(self->IsExceptionPending())) {
      return false;
    }
  }

  switch (field_type) {
    case Primitive::kPrimBoolean:
      result->SetZ(field->GetBoolean(obj));
      break;
    case Primitive::kPrimByte:
      result->SetB(field->GetByte(obj));
      break;
    case Primitive::kPrimChar:
      result->SetC(field->GetChar(obj));
      break;
    case Primitive::kPrimShort:
      result->SetS(field->GetShort(obj));
      break;
    case Primitive::kPrimInt:
      result->SetI(field->GetInt(obj));
      break;
    case Primitive::kPrimLong:
      result->SetJ(field->GetLong(obj));
      break;
    case Primitive::kPrimNot:
      result->SetL(field->GetObject(obj));
      break;
    case Primitive::kPrimVoid:
      LOG(FATAL) << "Unreachable " << field_type;
      break;
  }
  return true;
}

template<Primitive::Type field_type, bool do_assignability_check, bool transaction_active>
ALWAYS_INLINE bool DoFieldPutCommon(Thread* self,
                                    const ShadowFrame& shadow_frame,
                                    ObjPtr<mirror::Object> obj,
                                    ArtField* field,
                                    JValue& value)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  DCheckStaticState(self, field);

  // Report this field access to instrumentation if needed. Since we only have the offset of
  // the field from the base of the object, we need to look for it first.
  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
  if (UNLIKELY(instrumentation->HasFieldWriteListeners())) {
    StackHandleScope<2> hs(self);
    // Save this and return value (if needed) in case the instrumentation causes a suspend.
    HandleWrapperObjPtr<mirror::Object> h(hs.NewHandleWrapper(&obj));
    ObjPtr<mirror::Object> this_object = field->IsStatic() ? nullptr : obj;
    mirror::Object* fake_root = nullptr;
    HandleWrapper<mirror::Object> ret(hs.NewHandleWrapper<mirror::Object>(
        field_type == Primitive::kPrimNot ? value.GetGCRoot() : &fake_root));
    instrumentation->FieldWriteEvent(self,
                                     this_object.Ptr(),
                                     shadow_frame.GetMethod(),
                                     shadow_frame.GetDexPC(),
                                     field,
                                     value);
    if (UNLIKELY(self->IsExceptionPending())) {
      return false;
    }
    if (shadow_frame.GetForcePopFrame()) {
      // We need to check this here since we expect that the FieldWriteEvent happens before the
      // actual field write. If one pops the stack we should not modify the field.  The next
      // instruction will force a pop. Return true.
      DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
      DCHECK(interpreter::PrevFrameWillRetry(self, shadow_frame));
      return true;
    }
  }

  switch (field_type) {
    case Primitive::kPrimBoolean:
      field->SetBoolean<transaction_active>(obj, value.GetZ());
      break;
    case Primitive::kPrimByte:
      field->SetByte<transaction_active>(obj, value.GetB());
      break;
    case Primitive::kPrimChar:
      field->SetChar<transaction_active>(obj, value.GetC());
      break;
    case Primitive::kPrimShort:
      field->SetShort<transaction_active>(obj, value.GetS());
      break;
    case Primitive::kPrimInt:
      field->SetInt<transaction_active>(obj, value.GetI());
      break;
    case Primitive::kPrimLong:
      field->SetLong<transaction_active>(obj, value.GetJ());
      break;
    case Primitive::kPrimNot: {
      ObjPtr<mirror::Object> reg = value.GetL();
      if (do_assignability_check && reg != nullptr) {
        // FieldHelper::GetType can resolve classes, use a handle wrapper which will restore the
        // object in the destructor.
        ObjPtr<mirror::Class> field_class;
        {
          StackHandleScope<2> hs(self);
          HandleWrapperObjPtr<mirror::Object> h_reg(hs.NewHandleWrapper(&reg));
          HandleWrapperObjPtr<mirror::Object> h_obj(hs.NewHandleWrapper(&obj));
          field_class = field->ResolveType();
        }
        // ArtField::ResolveType() may fail as evidenced with a dexing bug (b/78788577).
        if (UNLIKELY(field_class.IsNull())) {
          Thread::Current()->AssertPendingException();
          return false;
        }
        if (UNLIKELY(!reg->VerifierInstanceOf(field_class.Ptr()))) {
          // This should never happen.
          std::string temp1, temp2, temp3;
          self->ThrowNewExceptionF("Ljava/lang/InternalError;",
                                   "Put '%s' that is not instance of field '%s' in '%s'",
                                   reg->GetClass()->GetDescriptor(&temp1),
                                   field_class->GetDescriptor(&temp2),
                                   field->GetDeclaringClass()->GetDescriptor(&temp3));
          return false;
        }
      }
      field->SetObj<transaction_active>(obj, reg);
      break;
    }
    case Primitive::kPrimVoid: {
      LOG(FATAL) << "Unreachable " << field_type;
      break;
    }
  }
  if (transaction_active) {
    if (UNLIKELY(self->IsExceptionPending())) {
      return false;
    }
  }
  return true;
}

}  // namespace art

#endif  // ART_RUNTIME_COMMON_DEX_OPERATIONS_H_
