/*
 * Copyright (C) 2011 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_OAT_RUNTIME_CONTEXT_H_
#define ART_SRC_OAT_RUNTIME_CONTEXT_H_

#include <stddef.h>
#include <stdint.h>

namespace art {

class StackVisitor;

// Representation of a thread's context on the executing machine
class Context {
 public:
  // Creates a context for the running architecture
  static Context* Create();

  virtual ~Context() {}

  // Read values from callee saves in the given frame. The frame also holds
  // the method that holds the layout.
  virtual void FillCalleeSaves(const StackVisitor& fr) = 0;

  // Set the stack pointer value
  virtual void SetSP(uintptr_t new_sp) = 0;

  // Set the program counter value
  virtual void SetPC(uintptr_t new_pc) = 0;

  // Read the given GPR
  virtual uintptr_t GetGPR(uint32_t reg) = 0;

  // Smash the caller save registers. If we're throwing, we don't want to return bogus values.
  virtual void SmashCallerSaves() = 0;

  // Switch execution of the executing context to this context
  virtual void DoLongJump() = 0;

  enum {
    kBadGprBase = 0xebad6070,
    kBadFprBase = 0xebad8070,
  };
};

class VmapTable {
 public:
  explicit VmapTable(const uint16_t* table) : table_(table) {
  }

  uint16_t operator[](size_t i) const {
    return table_[i + 1];
  }

  size_t size() const {
    return table_[0];
  }

  /*
   * WARNING: This code should be changed or renamed.  The "reg"
   * argument is a Dalvik virtual register number, but the way
   * the vmap and register promotion works a Dalvik vReg can have
   * neither, one or both of core register and floating point register
   * identities. The "INVALID_VREG" marker of 0xffff below separates the
   * core promoted registers from the floating point promoted registers,
   * and thus terminates the search before reaching the fp section.
   * This is likely the desired behavior for GC, as references won't
   * ever be promoted to float registers - but we'll probably want to
   * rework this shared code to make it useful for the debugger as well.
   */
  // Is register 'reg' in the context or on the stack?
  bool IsInContext(size_t reg, uint32_t& vmap_offset) const {
    vmap_offset = 0xEBAD0FF5;
    // TODO: take advantage of the registers being ordered
    for (size_t i = 0; i < size(); ++i) {
      // Stop if we find what we are are looking for...
      if (table_[i + 1] == reg) {
        vmap_offset = i;
        return true;
      }
      // ...or the INVALID_VREG that marks lr.
      // TODO: x86?
      if (table_[i + 1] == 0xffff) {
        break;
      }
    }
    return false;
  }

 private:
  const uint16_t* table_;
};

}  // namespace art

#endif  // ART_SRC_OAT_RUNTIME_CONTEXT_H_
