Exception Handling: libdex integration. Also added unit test on exception.

Runtime processing of TryItem and CatchHandler. Added iterator.

Next step: Exception Handling: RT integration. Implement throw and
unwind.

Change-Id: Idf88ce83e37b004016f1eca2c621e5a86948fe91
diff --git a/src/exception_test.cc b/src/exception_test.cc
new file mode 100644
index 0000000..ae1546f
--- /dev/null
+++ b/src/exception_test.cc
@@ -0,0 +1,105 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include <sys/mman.h>
+
+#include "assembler.h"
+#include "class_linker.h"
+#include "common_test.h"
+#include "dex_file.h"
+#include "jni_compiler.h"
+#include "runtime.h"
+#include "thread.h"
+#include "gtest/gtest.h"
+
+namespace art {
+
+// package java.lang;
+// import java.io.IOException;
+// class Object {};
+// public class MyClass {
+//   int f() throws Exception {
+//     try {
+//         g(1);
+//     } catch (IOException e) {
+//         return 1;
+//     } catch (Exception e) {
+//         return 2;
+//     }
+//     try {
+//         g(2);
+//     } catch (IOException e) {
+//         return 3;
+//     }
+//     return 0;
+//   }
+//   void g(int doThrow) throws Exception {
+//     if (doThrow == 1)
+//         throw new Exception();
+//     else if (doThrow == 2)
+//         throw new IOException();
+//   }
+// }
+
+static const char kMyClassExceptionHandleDex[] =
+  "ZGV4CjAzNQC/bXXtLZJLN1GzLr+ncrvPSl70n8t0yAjgAwAAcAAAAHhWNBIAAAAAAAAAACgDAAAN"
+  "AAAAcAAAAAcAAACkAAAAAwAAAMAAAAAAAAAAAAAAAAYAAADkAAAAAgAAABQBAACMAgAAVAEAAD4C"
+  "AABGAgAASQIAAGUCAAB8AgAAkwIAAKgCAAC8AgAAygIAAM0CAADRAgAA1AIAANcCAAABAAAAAgAA"
+  "AAMAAAAEAAAABQAAAAYAAAAIAAAAAQAAAAAAAAAAAAAACAAAAAYAAAAAAAAACQAAAAYAAAA4AgAA"
+  "AgABAAAAAAADAAEAAAAAAAQAAQAAAAAABAAAAAoAAAAEAAIACwAAAAUAAQAAAAAABQAAAAAAAAD/"
+  "////AAAAAAcAAAAAAAAACQMAAAAAAAAEAAAAAQAAAAUAAAAAAAAABwAAABgCAAATAwAAAAAAAAEA"
+  "AAABAwAAAQABAAAAAADeAgAAAQAAAA4AAAABAAEAAQAAAOMCAAAEAAAAcBAFAAAADgAEAAEAAgAC"
+  "AOgCAAAVAAAAEiISERIQbiAEAAMAEiBuIAQAAwASAA8ADQABECj9DQABICj6DQASMCj3AAADAAAA"
+  "AwABAAcAAAADAAYAAgICDAMPAQISAAAAAwACAAEAAAD3AgAAEwAAABIQMwIIACIAAwBwEAEAAAAn"
+  "ABIgMwIIACIAAgBwEAAAAAAnAA4AAAAAAAAAAAAAAAIAAAAAAAAAAwAAAFQBAAAEAAAAVAEAAAEA"
+  "AAAAAAY8aW5pdD4AAUkAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ABVMamF2YS9pby9JT0V4"
+  "Y2VwdGlvbjsAFUxqYXZhL2xhbmcvRXhjZXB0aW9uOwATTGphdmEvbGFuZy9NeUNsYXNzOwASTGph"
+  "dmEvbGFuZy9PYmplY3Q7AAxNeUNsYXNzLmphdmEAAVYAAlZJAAFmAAFnAAV2YWx1ZQADAAcOAAQA"
+  "Bw4ABwAHLFFOAnYsLR4tIR4AFQEABw48aTxpAAIBAQwcARgDAAABAAWAgATcAgAAAQICgYAE8AID"
+  "AIgDAQDgAwAAAA8AAAAAAAAAAQAAAAAAAAABAAAADQAAAHAAAAACAAAABwAAAKQAAAADAAAAAwAA"
+  "AMAAAAAFAAAABgAAAOQAAAAGAAAAAgAAABQBAAADEAAAAQAAAFQBAAABIAAABAAAAFwBAAAGIAAA"
+  "AQAAABgCAAABEAAAAQAAADgCAAACIAAADQAAAD4CAAADIAAABAAAAN4CAAAEIAAAAQAAAAEDAAAA"
+  "IAAAAgAAAAkDAAAAEAAAAQAAACgDAAA=";
+
+class ExceptionTest : public RuntimeTest {
+};
+
+TEST_F(ExceptionTest, MyClass_F_G) {
+  scoped_ptr<DexFile> dex(OpenDexFileBase64(kMyClassExceptionHandleDex));
+  PathClassLoader* class_loader = AllocPathClassLoader(dex.get());
+  Class* klass = class_linker_->FindClass("Ljava/lang/MyClass;", class_loader);
+  ASSERT_TRUE(klass != NULL);
+
+  Method* method_f = klass->FindVirtualMethod("f", "()I");
+  ASSERT_TRUE(method_f != NULL);
+
+  const DexFile& dex_file = class_linker_->FindDexFile(klass->GetDexCache());
+  const DexFile::CodeItem *code_item = dex_file.GetCodeItem(method_f->code_off_);
+
+  ASSERT_TRUE(code_item != NULL);
+
+  ASSERT_EQ(2u, code_item->tries_size_);
+  ASSERT_NE(0u, code_item->insns_size_);
+
+  const struct DexFile::TryItem *t0, *t1;
+  t0 = dex_file.dexGetTryItems(*code_item, 0);
+  t1 = dex_file.dexGetTryItems(*code_item, 1);
+  EXPECT_LE(t0->start_addr_, t1->start_addr_);
+
+  DexFile::CatchHandlerIterator iter =
+    dex_file.dexFindCatchHandler(*code_item, 4 /* Dex PC in the first try block */);
+  ASSERT_EQ(false, iter.End());
+  EXPECT_STREQ("Ljava/io/IOException;", dex_file.dexStringByTypeIdx(iter.Get().type_idx_));
+  iter.Next();
+  ASSERT_EQ(false, iter.End());
+  EXPECT_STREQ("Ljava/lang/Exception;", dex_file.dexStringByTypeIdx(iter.Get().type_idx_));
+  iter.Next();
+  ASSERT_EQ(true, iter.End());
+
+  iter = dex_file.dexFindCatchHandler(*code_item, 8 /* Dex PC in the second try block */);
+  ASSERT_EQ(false, iter.End());
+  EXPECT_STREQ("Ljava/io/IOException;", dex_file.dexStringByTypeIdx(iter.Get().type_idx_));
+  iter.Next();
+  ASSERT_EQ(true, iter.End());
+}
+
+}  // namespace art