/*
 * Copyright (C) 2015 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_INTERPRETER_UNSTARTED_RUNTIME_H_
#define ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_H_

#include "interpreter.h"

#include "base/macros.h"
#include "dex/dex_file.h"
#include "jvalue.h"
#include "unstarted_runtime_list.h"

namespace art HIDDEN {

class ArtMethod;
class CodeItemDataAccessor;
class Thread;
class ShadowFrame;

namespace mirror {
class Object;
}  // namespace mirror

namespace interpreter {

// Support for an unstarted runtime. These are special handwritten implementations for select
// libcore native and non-native methods so we can compile-time initialize classes in the boot
// image.
//
// While it would technically be OK to only expose the public functions, a class was chosen to
// wrap this so the actual implementations are exposed for testing. This is also why the private
// methods are not documented here - they are not intended to be used directly except in
// testing.

class UnstartedRuntime {
 public:
  EXPORT static void Initialize();

  // For testing. When we destroy the Runtime and create a new one,
  // we need to reinitialize maps with new `ArtMethod*` keys.
  static void Reinitialize();

  static void Invoke(Thread* self,
                     const CodeItemDataAccessor& accessor,
                     ShadowFrame* shadow_frame,
                     JValue* result,
                     size_t arg_offset)
      REQUIRES_SHARED(Locks::mutator_lock_);

  static void Jni(Thread* self,
                  ArtMethod* method,
                  mirror::Object* receiver,
                  uint32_t* args,
                  JValue* result)
      REQUIRES_SHARED(Locks::mutator_lock_);

 private:
  // Methods that intercept available libcore implementations.
#define UNSTARTED_DIRECT(ShortName, DescriptorIgnored, NameIgnored, SignatureIgnored) \
  static void Unstarted ## ShortName(Thread* self,                                    \
                                     ShadowFrame* shadow_frame,                       \
                                     JValue* result,                                  \
                                     size_t arg_offset)                               \
      REQUIRES_SHARED(Locks::mutator_lock_);
  UNSTARTED_RUNTIME_DIRECT_LIST(UNSTARTED_DIRECT)
#undef UNSTARTED_DIRECT

  // Methods that are native.
#define UNSTARTED_JNI(ShortName, DescriptorIgnored, NameIgnored, SignatureIgnored) \
  static void UnstartedJNI ## ShortName(Thread* self,                              \
                                        ArtMethod* method,                         \
                                        mirror::Object* receiver,                  \
                                        uint32_t* args,                            \
                                        JValue* result)                            \
      REQUIRES_SHARED(Locks::mutator_lock_);
  UNSTARTED_RUNTIME_JNI_LIST(UNSTARTED_JNI)
#undef UNSTARTED_JNI

  static void UnstartedClassForNameCommon(Thread* self,
                                          ShadowFrame* shadow_frame,
                                          JValue* result,
                                          size_t arg_offset,
                                          bool long_form) REQUIRES_SHARED(Locks::mutator_lock_);

  static void InitializeInvokeHandlers(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
  static void InitializeJNIHandlers(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);

  friend class UnstartedRuntimeTest;

  DISALLOW_ALLOCATION();
  DISALLOW_COPY_AND_ASSIGN(UnstartedRuntime);
};

}  // namespace interpreter
}  // namespace art

#endif  // ART_RUNTIME_INTERPRETER_UNSTARTED_RUNTIME_H_
