Interpreter.

The opcodes filled-new-array and packed-switch aren't implemented but
are trivial given that they are variants of implemented opcodes.
Refactor Field::Get routines to take the declaring class in the case of
static field accesses. This avoids a check on every use of a field.
Refactor arg array builder to be shared by JNI invokes and invocations
into the interpreter.
Fix benign bug in const decoding in the verifier.

Change-Id: I8dee6c1f4b7f033e6c003422c56e9471cfaccda8
diff --git a/src/stack.h b/src/stack.h
index 845b840..3cf8577 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -37,6 +37,14 @@
 
 class ShadowFrame {
  public:
+  static ShadowFrame* Create(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link,
+                             AbstractMethod* method, uint32_t dex_pc) {
+    size_t sz = sizeof(ShadowFrame) + (sizeof(Object*) * num_refs) + (sizeof(uint32_t) * num_vregs);
+    uint8_t* memory = new uint8_t[sz];
+    return new (memory) ShadowFrame(num_refs, num_vregs, link, method, dex_pc);
+  }
+  ~ShadowFrame() {}
+
   uint32_t NumberOfReferences() const {
     return number_of_references_;
   }
@@ -76,6 +84,59 @@
     references_[i] = object;
   }
 
+  int32_t GetVReg(size_t i) const {
+    DCHECK_LT(i, number_of_vregs_);
+    const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
+    return reinterpret_cast<const int32_t*>(vregs)[i];
+  }
+
+  float GetVRegFloat(size_t i) const {
+    DCHECK_LT(i, number_of_vregs_);
+    const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
+    return reinterpret_cast<const float*>(vregs)[i];
+  }
+
+  int64_t GetVRegLong(size_t i) const {
+    const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
+    const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
+    return *reinterpret_cast<const int64_t*>(low_half);
+  }
+
+  double GetVRegDouble(size_t i) const {
+    const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
+    const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
+    return *reinterpret_cast<const double*>(low_half);
+  }
+
+  void SetVReg(size_t i, int32_t val) {
+    DCHECK_LT(i, number_of_vregs_);
+    int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
+    reinterpret_cast<int32_t*>(vregs)[i] = val;
+  }
+
+  void SetVRegFloat(size_t i, float val) {
+    DCHECK_LT(i, number_of_vregs_);
+    int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
+    reinterpret_cast<float*>(vregs)[i] = val;
+  }
+
+  void SetVRegLong(size_t i, int64_t val) {
+    int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
+    int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
+    *reinterpret_cast<int64_t*>(low_half) = val;
+  }
+
+  void SetVRegDouble(size_t i, double val) {
+    int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
+    int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
+    *reinterpret_cast<double*>(low_half) = val;
+  }
+
+  void SetReferenceAndVReg(size_t i, Object* val) {
+    SetReference(i, val);
+    SetVReg(i, reinterpret_cast<int32_t>(val));
+  }
+
   AbstractMethod* GetMethod() const {
     DCHECK_NE(method_, static_cast<void*>(NULL));
     return method_;
@@ -126,22 +187,31 @@
     return OFFSETOF_MEMBER(ShadowFrame, references_);
   }
 
-  size_t VRegsOffset() {
+  size_t VRegsOffset() const {
     return ReferencesOffset() + (sizeof(Object*) * NumberOfReferences());
   }
 
  private:
-  // ShadowFrame should be allocated by the generated code directly.
-  // We should not create new shadow stack in the runtime support function.
-  ~ShadowFrame() {}
+  ShadowFrame(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link, AbstractMethod* method,
+              uint32_t dex_pc)
+      : number_of_references_ (num_refs), number_of_vregs_(num_vregs), link_(link),
+        method_(method), dex_pc_(dex_pc) {
+    for (size_t i = 0; i < num_refs; ++i) {
+      SetReference(i, NULL);
+    }
+    for (size_t i = 0; i < num_vregs; ++i) {
+      SetVReg(i, 0);
+    }
+  }
 
+  // TODO: make the majority of these fields const.
   uint16_t number_of_references_;
   uint16_t number_of_vregs_;
   // Link to previous shadow frame or NULL.
   ShadowFrame* link_;
   AbstractMethod* method_;
   uint32_t dex_pc_;
-  Object* references_[];
+  Object* references_[0];
 
   DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
 };