harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mloe...@apache.org
Subject svn commit: r584118 [1/6] - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/vmcore/include/ vm/vmcore/src/class_support/ vm/vmcore/src/verifier-3363/ vm/vmcore/src/verifier-3363/base/ vm/vmcore/src/verifier-3363/java5/ vm/vmcore/src/veri...
Date Fri, 12 Oct 2007 10:32:52 GMT
Author: mloenko
Date: Fri Oct 12 03:32:50 2007
New Revision: 584118

URL: http://svn.apache.org/viewvc?rev=584118&view=rev
Log:
verifier refactoring: integration of the second patch of HARMONY-4818

Added:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.cpp
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass1.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.h
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_x.cpp
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_x.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/instr_props.h
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/instr_props.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/stackmap.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/stackmap_x.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Ver.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver_utils.h
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/vf_resolve.cpp
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/context_5.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/instr_props_5.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java5/stackmap_5.h
      - copied, changed from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/stackmap.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java6/
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java6/context_6.cpp   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java6/context_6.h   (with props)
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/java6/stackmap_6.h   (with props)
Removed:
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass1.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass2.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Ver.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/instr_props.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/stackmap.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp
Modified:
    harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_interface.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/include/verifier.h
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
    harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp

Modified: harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml (original)
+++ harmony/enhanced/drlvm/trunk/build/make/components/vm/vmcore.xml Fri Oct 12 03:32:50 2007
@@ -86,7 +86,7 @@
                 <include name="thread/helpers/thread_helpers_${build.arch}.cpp" />
                 <include name="util/*.cpp" />
                 <include name="verifier/*.cpp" if="use_original_verifier"/>
-                <include name="verifier-3363/*.cpp" unless="use_original_verifier"/>
+                <include name="verifier-3363/*/*.cpp" unless="use_original_verifier"/>
             </fileset>
 
             <fileset dir="${build.vm.home}/vmcore/src/kernel_classes/native">

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_interface.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_interface.h?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_interface.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_interface.h Fri Oct 12 03:32:50 2007
@@ -493,6 +493,21 @@
 const char *
 method_get_exc_method_can_throw( method_handler hmethod, unsigned short index );
 
+
+/**
+ * Gets StackMapTable attribute.
+ * Parameter <i>hmethod</i> must not equal to <code>NULL</code>.
+ * If parameter <i>index</i> is out of range, returns <code>NULL</code>.
+ *
+ * @param hmethod   method handle
+ *
+ * @return          StackMapTable bytes
+ */
+unsigned char *
+method_get_stackmaptable( method_handler hmethod );
+
+
+
 /**
  * Class loader interface
  */

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/class_member.h Fri Oct 12 03:32:50 2007
@@ -49,6 +49,7 @@
     ATTR_RuntimeVisibleParameterAnnotations,    // Method
     ATTR_RuntimeInvisibleParameterAnnotations,  // Method
     ATTR_AnnotationDefault,     // Method (spec does not limit number???)
+    ATTR_StackMapTable,         // Method
     N_ATTR,
     ATTR_UNDEF,
     ATTR_ERROR
@@ -812,6 +813,15 @@
     {
         pending_breakpoints--;
     }
+
+
+    uint8* m_stackmap;
+public:
+    uint8* get_stackmap() {
+        return m_stackmap;
+    }
+
+
 }; // Method
 
 #endif

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/include/verifier.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/include/verifier.h?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/include/verifier.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/include/verifier.h Fri Oct 12 03:32:50 2007
@@ -47,6 +47,7 @@
     VF_ErrorJsrOther,           // invalid subroutine
     VF_ClassNotLoaded,          // verified class not loaded yet
     VF_ErrorInternal,           // error in verification process
+    VF_ErrorStackmap,           // error in stackmap attribute
     VF_Continue                 // intermediate status, continue analysis
 };
 

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/Class_File_Loader.cpp Fri Oct 12 03:32:50 2007
@@ -147,6 +147,7 @@
     {"LineNumberTable", NULL, ATTR_LineNumberTable},
     {"LocalVariableTable", NULL, ATTR_LocalVariableTable},
     {"LocalVariableTypeTable", NULL, ATTR_LocalVariableTypeTable},
+    {"StackMapTable", NULL, ATTR_StackMapTable},
     {NULL, NULL, ATTR_UNDEF}
 };
  
@@ -1470,6 +1471,9 @@
     unsigned num_lvt_entries = 0;
     unsigned num_lvtt_entries = 0;
 
+    unsigned numStackMap = 0;
+    m_stackmap = 0;
+
     for (i=0; i<n_attrs; i++) {
         Attributes cur_attr = parse_attribute(_class, cfs, code_attrs, &attr_len);
         switch(cur_attr) {
@@ -1578,6 +1582,32 @@
                 }
                 break;
             }
+
+        case ATTR_StackMapTable:
+            //TODO: skip if classfile version less than 50
+            numStackMap++;
+            if (numStackMap > 1) {
+                REPORT_FAILED_METHOD(" there is more than one StackMap attribute");
+                return false;
+            }
+
+            m_stackmap = (uint8*)Method::Alloc(attr_len + 6);
+            if(!cfs.skip(-6)) { // read once again attribute head
+                REPORT_FAILED_CLASS_CLASS(_class->get_class_loader(), _class, "java/lang/InternalError",
+                    _class->get_name()->bytes << ": inernal error: unable to read beginning of an attribute");
+                return false;
+            }
+
+            unsigned i;
+            for (i=0; i<attr_len + 6; i++) {
+                if(!cfs.parse_u1(&m_stackmap[i])) {
+                    REPORT_FAILED_METHOD("truncated class file: failed to parse bytecode");
+                    return false;
+                }
+            }
+
+            break;
+
         case ATTR_UNDEF:
             // unrecognized attribute; skipped
             break;

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp?rev=584118&r1=584117&r2=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/class_support/class_impl.cpp Fri Oct 12 03:32:50 2007
@@ -509,6 +509,17 @@
 } // method_get_exc_method_can_throw
 
 /**
+ * Gets StackMapTable attribute bytes.
+ */
+unsigned char *
+method_get_stackmaptable( method_handler hmethod)
+{
+    assert( hmethod );
+    Method *method = (Method*)hmethod;
+    return method->get_stackmap();
+} // method_get_stackmaptable
+
+/**
  * Function sets verify data in class loader.
  */
 void

Copied: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.cpp (from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass1.cpp)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.cpp?p2=harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.cpp&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass1.cpp&r1=584094&r2=584118&rev=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/Pass1.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.cpp Fri Oct 12 03:32:50 2007
@@ -18,464 +18,370 @@
  * @author Mikhail Loenko, Vladimir Molotkov
  */  
 
-#include "stackmap.h"
-#include "context.h"
-
-namespace CPVerifier {
-
-    // data for parsing for each instruction (length and flags)
-    ParseInfo vf_Context_t::parseTable[255] = {
-
-        /* 0x00 OP_NOP */           { 1, 0 },
-
-        /* 0x01 OP_ACONST_NULL */   { 1, 0 },
-        /* 0x02 OP_ICONST_M1 */     { 1, 0 },
-        /* 0x03 OP_ICONST_0 */      { 1, 0 },
-        /* 0x04 OP_ICONST_1 */      { 1, 0 },
-        /* 0x05 OP_ICONST_2 */      { 1, 0 },
-        /* 0x06 OP_ICONST_3 */      { 1, 0 },
-        /* 0x07 OP_ICONST_4 */      { 1, 0 },
-        /* 0x08 OP_ICONST_5 */      { 1, 0 },
-        /* 0x09 OP_LCONST_0 */      { 1, 0 },
-        /* 0x0a OP_LCONST_1 */      { 1, 0 },
-        /* 0x0b OP_FCONST_0 */      { 1, 0 },
-        /* 0x0c OP_FCONST_1 */      { 1, 0 },
-        /* 0x0d OP_FCONST_2 */      { 1, 0 },
-        /* 0x0e OP_DCONST_0 */      { 1, 0 },
-        /* 0x0f OP_DCONST_1 */      { 1, 0 },
-
-        /* 0x10 OP_BIPUSH */        { 2, 0 },
-        /* 0x11 OP_SIPUSH */        { 3, 0 },
-
-        /* 0x12 OP_LDC */           { 2, 0 },
-        /* 0x13 OP_LDC_W */         { 3, 0 },
-        /* 0x14 OP_LDC2_W */        { 3, 0 },
-
-        /* 0x15 OP_ILOAD */         { 2, PI_CANWIDE },
-        /* 0x16 OP_LLOAD */         { 2, PI_CANWIDE },
-        /* 0x17 OP_FLOAD */         { 2, PI_CANWIDE },
-        /* 0x18 OP_DLOAD */         { 2, PI_CANWIDE },
-        /* 0x19 OP_ALOAD */         { 2, PI_CANWIDE },
-
-        /* 0x1a OP_ILOAD_0 */       { 1, 0 },
-        /* 0x1b OP_ILOAD_1 */       { 1, 0 },
-        /* 0x1c OP_ILOAD_2 */       { 1, 0 },
-        /* 0x1d OP_ILOAD_3 */       { 1, 0 },
-        /* 0x1e OP_LLOAD_0 */       { 1, 0 },
-        /* 0x1f OP_LLOAD_1 */       { 1, 0 },
-        /* 0x20 OP_LLOAD_2 */       { 1, 0 },
-        /* 0x21 OP_LLOAD_3 */       { 1, 0 },
-        /* 0x22 OP_FLOAD_0 */       { 1, 0 },
-        /* 0x23 OP_FLOAD_1 */       { 1, 0 },
-        /* 0x24 OP_FLOAD_2 */       { 1, 0 },
-        /* 0x25 OP_FLOAD_3 */       { 1, 0 },
-        /* 0x26 OP_DLOAD_0 */       { 1, 0 },
-        /* 0x27 OP_DLOAD_1 */       { 1, 0 },
-        /* 0x28 OP_DLOAD_2 */       { 1, 0 },
-        /* 0x29 OP_DLOAD_3 */       { 1, 0 },
-        /* 0x2a OP_ALOAD_0 */       { 1, 0 },
-        /* 0x2b OP_ALOAD_1 */       { 1, 0 },
-        /* 0x2c OP_ALOAD_2 */       { 1, 0 },
-        /* 0x2d OP_ALOAD_3 */       { 1, 0 },
-
-        /* 0x2e OP_IALOAD */        { 1, 0 },
-        /* 0x2f OP_LALOAD */        { 1, 0 },
-        /* 0x30 OP_FALOAD */        { 1, 0 },
-        /* 0x31 OP_DALOAD */        { 1, 0 },
-        /* 0x32 OP_AALOAD */        { 1, 0 },
-        /* 0x33 OP_BALOAD */        { 1, 0 },
-        /* 0x34 OP_CALOAD */        { 1, 0 },
-        /* 0x35 OP_SALOAD */        { 1, 0 },
-
-        /* 0x36 OP_ISTORE */        { 2, PI_CANWIDE },
-        /* 0x37 OP_LSTORE */        { 2, PI_CANWIDE },
-        /* 0x38 OP_FSTORE */        { 2, PI_CANWIDE },
-        /* 0x39 OP_DSTORE */        { 2, PI_CANWIDE },
-        /* 0x3a OP_ASTORE */        { 2, PI_CANWIDE },
-
-        /* 0x3b OP_ISTORE_0 */      { 1, 0 },
-        /* 0x3c OP_ISTORE_1 */      { 1, 0 },
-        /* 0x3d OP_ISTORE_2 */      { 1, 0 },
-        /* 0x3e OP_ISTORE_3 */      { 1, 0 },
-        /* 0x3f OP_LSTORE_0 */      { 1, 0 },
-        /* 0x40 OP_LSTORE_1 */      { 1, 0 },
-        /* 0x41 OP_LSTORE_2 */      { 1, 0 },
-        /* 0x42 OP_LSTORE_3 */      { 1, 0 },
-        /* 0x43 OP_FSTORE_0 */      { 1, 0 },
-        /* 0x44 OP_FSTORE_1 */      { 1, 0 },
-        /* 0x45 OP_FSTORE_2 */      { 1, 0 },
-        /* 0x46 OP_FSTORE_3 */      { 1, 0 },
-        /* 0x47 OP_DSTORE_0 */      { 1, 0 },
-        /* 0x48 OP_DSTORE_1 */      { 1, 0 },
-        /* 0x49 OP_DSTORE_2 */      { 1, 0 },
-        /* 0x4a OP_DSTORE_3 */      { 1, 0 },
-        /* 0x4b OP_ASTORE_0 */      { 1, 0 },
-        /* 0x4c OP_ASTORE_1 */      { 1, 0 },
-        /* 0x4d OP_ASTORE_2 */      { 1, 0 },
-        /* 0x4e OP_ASTORE_3 */      { 1, 0 },
-
-        /* 0x4f OP_IASTORE */       { 1, 0 },
-        /* 0x50 OP_LASTORE */       { 1, 0 },
-        /* 0x51 OP_FASTORE */       { 1, 0 },
-        /* 0x52 OP_DASTORE */       { 1, 0 },
-        /* 0x53 OP_AASTORE */       { 1, 0 },
-        /* 0x54 OP_BASTORE */       { 1, 0 },
-        /* 0x55 OP_CASTORE */       { 1, 0 },
-        /* 0x56 OP_SASTORE */       { 1, 0 },
-
-        /* 0x57 OP_POP */           { 1, 0 },
-        /* 0x58 OP_POP2 */          { 1, 0 },
-
-        /* 0x59 OP_DUP */           { 1, 0 },
-        /* 0x5a OP_DUP_X1 */        { 1, 0 },
-        /* 0x5b OP_DUP_X2 */        { 1, 0 },
-        /* 0x5c OP_DUP2 */          { 1, 0 },
-        /* 0x5d OP_DUP2_X1 */       { 1, 0 },
-        /* 0x5e OP_DUP2_X2 */       { 1, 0 },
-
-        /* 0x5f OP_SWAP */          { 1, 0 },
-
-        /* 0x60 OP_IADD */          { 1, 0 },
-        /* 0x61 OP_LADD */          { 1, 0 },
-        /* 0x62 OP_FADD */          { 1, 0 },
-        /* 0x63 OP_DADD */          { 1, 0 },
-        /* 0x64 OP_ISUB */          { 1, 0 },
-        /* 0x65 OP_LSUB */          { 1, 0 },
-        /* 0x66 OP_FSUB */          { 1, 0 },
-        /* 0x67 OP_DSUB */          { 1, 0 },
-        /* 0x68 OP_IMUL */          { 1, 0 },
-        /* 0x69 OP_LMUL */          { 1, 0 },
-        /* 0x6a OP_FMUL */          { 1, 0 },
-        /* 0x6b OP_DMUL */          { 1, 0 },
-        /* 0x6c OP_IDIV */          { 1, 0 },
-        /* 0x6d OP_LDIV */          { 1, 0 },
-        /* 0x6e OP_FDIV */          { 1, 0 },
-        /* 0x6f OP_DDIV */          { 1, 0 },
-        /* 0x70 OP_IREM */          { 1, 0 },
-        /* 0x71 OP_LREM */          { 1, 0 },
-        /* 0x72 OP_FREM */          { 1, 0 },
-        /* 0x73 OP_DREM */          { 1, 0 },
-        /* 0x74 OP_INEG */          { 1, 0 },
-        /* 0x75 OP_LNEG */          { 1, 0 },
-        /* 0x76 OP_FNEG */          { 1, 0 },
-        /* 0x77 OP_DNEG */          { 1, 0 },
-        /* 0x78 OP_ISHL */          { 1, 0 },
-        /* 0x79 OP_LSHL */          { 1, 0 },
-        /* 0x7a OP_ISHR */          { 1, 0 },
-        /* 0x7b OP_LSHR */          { 1, 0 },
-        /* 0x7c OP_IUSHR */         { 1, 0 },
-        /* 0x7d OP_LUSHR */         { 1, 0 },
-        /* 0x7e OP_IAND */          { 1, 0 },
-        /* 0x7f OP_LAND */          { 1, 0 },
-        /* 0x80 OP_IOR */           { 1, 0 },
-        /* 0x81 OP_LOR */           { 1, 0 },
-        /* 0x82 OP_IXOR */          { 1, 0 },
-        /* 0x83 OP_LXOR */          { 1, 0 },
-
-        /* 0x84 OP_IINC */          { 3, PI_CANWIDE },
-
-        /* 0x85 OP_I2L */           { 1, 0 },
-        /* 0x86 OP_I2F */           { 1, 0 },
-        /* 0x87 OP_I2D */           { 1, 0 },
-        /* 0x88 OP_L2I */           { 1, 0 },
-        /* 0x89 OP_L2F */           { 1, 0 },
-        /* 0x8a OP_L2D */           { 1, 0 },
-        /* 0x8b OP_F2I */           { 1, 0 },
-        /* 0x8c OP_F2L */           { 1, 0 },
-        /* 0x8d OP_F2D */           { 1, 0 },
-        /* 0x8e OP_D2I */           { 1, 0 },
-        /* 0x8f OP_D2L */           { 1, 0 },
-        /* 0x90 OP_D2F */           { 1, 0 },
-        /* 0x91 OP_I2B */           { 1, 0 },
-        /* 0x92 OP_I2C */           { 1, 0 },
-        /* 0x93 OP_I2S */           { 1, 0 },
-
-        /* 0x94 OP_LCMP */          { 1, 0 },
-        /* 0x95 OP_FCMPL */         { 1, 0 },
-        /* 0x96 OP_FCMPG */         { 1, 0 },
-        /* 0x97 OP_DCMPL */         { 1, 0 },
-        /* 0x98 OP_DCMPG */         { 1, 0 },
-
-        /* 0x99 OP_IFEQ */          { 3, PI_JUMP },
-        /* 0x9a OP_IFNE */          { 3, PI_JUMP },
-        /* 0x9b OP_IFLT */          { 3, PI_JUMP },
-        /* 0x9c OP_IFGE */          { 3, PI_JUMP },
-        /* 0x9d OP_IFGT */          { 3, PI_JUMP },
-        /* 0x9e OP_IFLE */          { 3, PI_JUMP },
-        /* 0x9f OP_IF_ICMPEQ */     { 3, PI_JUMP },
-        /* 0xa0 OP_IF_ICMPNE */     { 3, PI_JUMP },
-        /* 0xa1 OP_IF_ICMPLT */     { 3, PI_JUMP },
-        /* 0xa2 OP_IF_ICMPGE */     { 3, PI_JUMP },
-        /* 0xa3 OP_IF_ICMPGT */     { 3, PI_JUMP },
-        /* 0xa4 OP_IF_ICMPLE */     { 3, PI_JUMP },
-        /* 0xa5 OP_IF_ACMPEQ */     { 3, PI_JUMP },
-        /* 0xa6 OP_IF_ACMPNE */     { 3, PI_JUMP },
-
-        /* 0xa7 OP_GOTO */          { 3, PI_JUMP | PI_DIRECT },
-
-        /* 0xa8 OP_JSR */           { 3, PI_JUMP},
-        /* 0xa9 OP_RET */           { 2, PI_DIRECT | PI_CANWIDE },
-
-        /* 0xaa OP_TABLESWITCH */   { 16, PI_SWITCH },
-        /* 0xab OP_LOOKUPSWITCH */  { 9, PI_SWITCH },
-
-        /* 0xac OP_IRETURN */       { 1, PI_DIRECT },
-        /* 0xad OP_LRETURN */       { 1, PI_DIRECT },
-        /* 0xae OP_FRETURN */       { 1, PI_DIRECT },
-        /* 0xaf OP_DRETURN */       { 1, PI_DIRECT },
-        /* 0xb0 OP_ARETURN */       { 1, PI_DIRECT },
-        /* 0xb1 OP_RETURN */        { 1, PI_DIRECT },
-
-        /* 0xb2 OP_GETSTATIC */     { 3, 0 },
-        /* 0xb3 OP_PUTSTATIC */     { 3, 0 },
-        /* 0xb4 OP_GETFIELD */      { 3, 0 },
-        /* 0xb5 OP_PUTFIELD */      { 3, 0 },
-
-        /* 0xb6 OP_INVOKEVIRTUAL */ { 3, 0 },
-        /* 0xb7 OP_INVOKESPECIAL */ { 3, 0 },
-        /* 0xb8 OP_INVOKESTATIC */  { 3, 0 },
-
-        /* 0xb9 OP_INVOKEINTERFACE */ { 5, 0 },
-
-        /* oxba XXX_UNUSED_XXX */   {0, 0},
-
-        /* 0xbb OP_NEW */           { 3, 0 },
-        /* 0xbc OP_NEWARRAY */      { 2, 0 },
-        /* 0xbd OP_ANEWARRAY */     { 3, 0 },
-
-        /* 0xbe OP_ARRAYLENGTH */   { 1, 0 },
-
-        /* 0xbf OP_ATHROW */        { 1, PI_DIRECT },
-
-        /* 0xc0 OP_CHECKCAST */     { 3, 0 },
-        /* 0xc1 OP_INSTANCEOF */    { 3, 0 },
-
-        /* 0xc2 OP_MONITORENTER */  { 1, 0 },
-        /* 0xc3 OP_MONITOREXIT */   { 1, 0 },
-
-        /* 0xc4 OP_WIDE */          { 2, 0 },
-
-        /* 0xc5 OP_MULTIANEWARRAY */{ 4, 0 },
-
-        /* 0xc6 OP_IFNULL */        { 3, PI_JUMP },
-        /* 0xc7 OP_IFNONNULL */     { 3, PI_JUMP },
-
-        /* 0xc8 OP_GOTO_W */        { 5, PI_JUMP | PI_DIRECT | PI_WIDEJUMP },
-        /* 0xc9 OP_JSR_W */         { 5, PI_JUMP | PI_WIDEJUMP },
-    };
-
-    /////////////////////////////////////////////////////////////////////////////////////
-
-    /*
-    * Obtain the length of a compound instruction
-    */
-    int vf_Context_t::instr_get_len_compound(Address instr, OpCode opcode) {
-        if( opcode == OP_WIDE ) {
-            ParseInfo &pi = instr_get_parse_info( (OpCode)m_bytecode[instr+1] );
-
-            if( !(pi.flags & PI_CANWIDE) ) {
-                // return some big value - error will occur later
-                return 0x20000123;
-            }
-
-            return 2*pi.instr_min_len;
-        }
-
-
-        Address def_adr = (instr & (~3) ) + 4;
-        if( opcode == OP_TABLESWITCH) {
-            int lowbyte = read_int32(m_bytecode + def_adr + 4);
-            int hibyte = read_int32(m_bytecode + def_adr + 8);
-
-            // protect from integer overflow
-            if( hibyte < lowbyte || hibyte - lowbyte > 0x20000000) {
-                // return some big value - error will occur later
-                return 0x20000123;
-            }
-
-            return def_adr + 12 + (hibyte - lowbyte + 1) * 4 - instr;
-        } else {
-            assert( opcode == OP_LOOKUPSWITCH );
-
-            //minimal length of OP_LOOKUPSWITCH is 9 bytes, while its required value may exceed 9 bytes, have to check bounds
-            if( (unsigned)def_adr + 8 > m_code_length ) {
-                // return some big value - error will occur later
-                return 0x20000123;
-            }
-
-            unsigned npairs = read_int32(m_bytecode + def_adr + 4);
-
-            // protect from integer overflow
-            if( npairs > 0x20000000) {
-                // return some big value - error will occur later
-                return 0x20000123;
-            }
-
-            int next = def_adr + 8;
-
-            if (npairs) {
-                int old_value = read_int32(m_bytecode + next);
-                next += 8;
-                // integer values must be sorted - verify
-                for( unsigned i = 1; i < npairs; i++) {
-                    int new_value = read_int32(m_bytecode + next);
-                    next += 8;
-                    if( old_value >= new_value ) {
-                        // return some big value - error will occur later
-                        return 0x20000123;
-                    }
-                    old_value = new_value;
-                }
-            }
-
-            return next - instr;
-        }
-    }
-
-    /*
-    This method makes the first pass through the instruction set.
-    On that pass we check that all instruction have valid opcode, that no
-    jumps, no exception handlers lead to the middle of instruction nor 
-    out of the method. it checks that control does not flow out of the method.
-
-    It also finds all instructions that have multiple predecessors 
-    (like goto tagrtes), this information will be used on the second Pass
-
-    Method starts with the instruction <code>instr</code> for each it was invoked and go down 
-    filling the mask array with the flags. On this pass it distignushes
-    4 types of instructions:
-    0 - non-passed instruction or dead code
-    1 - passed instruction
-    2 - middle of passed instruction
-    3 - passed multiway instruction (having many predecessors)
-
-    If the method comes to a return, ret, athrow, or an already passed instruction, it terminates
-    If it comes to a switch, an if, or a jsr then it push all branches onto the stack
-    If it comes to a goto then it continues from the jump target
-    */
-
-    vf_Result vf_Context_t::parse(Address instr) {
-        // instruction is out of the method or in the middle of another instruction
-        if( instr > m_code_length || props.isOperand(instr) ) {
-            return error(VF_ErrorCodeEnd, "jump to the middle of instruction or out of the method");
-        }
-
-        while( instr < m_code_length ) {
-            if( props.isParsePassed(instr) ) {
-                // more than one branch leads to this instruction
-                if( !dead_code_parsing ) {
-                    props.setMultiway(instr);
-                }
-                return VF_OK;
-            }
-
-            OpCode opcode = (OpCode)m_bytecode[instr];
-            processed_instruction = instr;
-
-            // does code correspond to any valid instruction?
-            if( !instr_is_valid_bytecode(opcode) ) {
-                return error(VF_ErrorInstruction, "invalid opcode");
-            }
-
-            // keep all nessesary information about instruction
-            ParseInfo &pi = instr_get_parse_info(opcode);
-
-            // get MINIMAL length of the instruction with operands
-            unsigned instr_len = instr_get_minlen(pi);
-
-            // code does not correspond to any valid instruction or method length is less than required
-            if( instr + instr_len > m_code_length ) {
-                return error(VF_ErrorInstruction, "method length is less than required");
-            }
-
-            if( instr_is_compound(opcode, pi) ) {
-                // get ACTUAL length for variable length insgtructions
-                instr_len = instr_get_len_compound(instr, opcode);
-
-                // method length is less than required
-                if( instr + instr_len > m_code_length ) {
-                    return error(VF_ErrorInstruction, "compound instruction: method length is less than required");
-                }
-            }
-
-            // mark this instruction as processed
-            assert( !props.isParsePassed(instr) );
-            props.setParsePassed(instr);
-
-            // check that no other instruction jumps to the middle of the current instruction
-            for( Address i = instr + 1; i < instr + instr_len; i++ ) {
-                if( !props.setOperand(i) ) {
-                    return error(VF_ErrorUnknown, "jump to the middle of instruction");
-                }
-            }
-
-
-
-            if( instr_is_regular(pi) ) {
-                //regular instruction - go to the next instruction
-                instr += instr_len;
-            } else if( instr_is_jump(pi) ) {
-                // goto, goto_w, if*
-
-                Address target = instr_get_jump_target(pi, m_bytecode, instr);
-
-                // jump out of method or to the middle of an instruction
-                if( target >= m_code_length || props.isOperand(target) ) {
-                    return error(VF_ErrorBranch, "jump out of method or to the middle of an instruction");
-                }
-
-                if( instr_direct(pi, opcode, m_bytecode, instr) ) {
-                    //TODO: though the spec does not require to check the dead code for correctness
-                    //RI seems to check it and some Harmony negative tests have broken dead code
-
-                    dead_code_stack.push(instr+instr_len);
-
-                    instr = target; // it is not an if* - go to jump target
-                } else {
-                    // process conditional jump target or jsr
-                    stack.push(target);
-
-                    // go to the next instruction
-                    instr += instr_len;
-                }
-            } else if( instr_direct(pi, opcode, m_bytecode, instr) ) {
-                dead_code_stack.push(instr+instr_len);
-
-                // it is not a jump ==> it is return or throw or ret
-                return VF_OK;
-            } else {
-                assert( instr_is_switch(pi) );
-
-                Address next_target_adr = (instr & (~3) ) + 4;
-
-                //default target
-                Address target = instr + read_int32(m_bytecode + next_target_adr);
-                stack.push(target);
-
-                // in tableswitch instruction target offsets are stored with shift = 4,
-                // in lookupswitch with shift = 8
-                int shift = (opcode == OP_TABLESWITCH) ? 4 : 8;
-
-                for (next_target_adr += 12;
-                    next_target_adr < instr + instr_len;
-                    next_target_adr += shift)
-                {
-                    target = instr + read_int32(m_bytecode + next_target_adr);
-                    // jump out of method or to the middle of an instruction
-                    if( target >= m_code_length || props.isOperand(target) ) {
-                        return error(VF_ErrorBranch, "jump out of method or to the middle of an instruction");
-                    }
-                    // process conditional jump target
-                    stack.push(target);
-                }
-
-                return VF_OK;
-            }
-        }
-
-        //it might be a dead code -- code followed by JSR which never returns
-        //if it's a dead code - it's OK, if it's not - we will catch it on the second pass
-        return VF_OK;
-    }
-
-} // namespace CPVerifier
+#include "verifier.h"
+#include "context_base.h"
+namespace CPVerifier {
+
+
+
+    /**
+    * data for parsing for each instruction (length and flags)
+    */
+    ParseInfo vf_Context_Base::parseTable[255] = {
+
+        /* 0x00 OP_NOP */           { 1, 0 },
+
+        /* 0x01 OP_ACONST_NULL */   { 1, 0 },
+        /* 0x02 OP_ICONST_M1 */     { 1, 0 },
+        /* 0x03 OP_ICONST_0 */      { 1, 0 },
+        /* 0x04 OP_ICONST_1 */      { 1, 0 },
+        /* 0x05 OP_ICONST_2 */      { 1, 0 },
+        /* 0x06 OP_ICONST_3 */      { 1, 0 },
+        /* 0x07 OP_ICONST_4 */      { 1, 0 },
+        /* 0x08 OP_ICONST_5 */      { 1, 0 },
+        /* 0x09 OP_LCONST_0 */      { 1, 0 },
+        /* 0x0a OP_LCONST_1 */      { 1, 0 },
+        /* 0x0b OP_FCONST_0 */      { 1, 0 },
+        /* 0x0c OP_FCONST_1 */      { 1, 0 },
+        /* 0x0d OP_FCONST_2 */      { 1, 0 },
+        /* 0x0e OP_DCONST_0 */      { 1, 0 },
+        /* 0x0f OP_DCONST_1 */      { 1, 0 },
+
+        /* 0x10 OP_BIPUSH */        { 2, 0 },
+        /* 0x11 OP_SIPUSH */        { 3, 0 },
+
+        /* 0x12 OP_LDC */           { 2, 0 },
+        /* 0x13 OP_LDC_W */         { 3, 0 },
+        /* 0x14 OP_LDC2_W */        { 3, 0 },
+
+        /* 0x15 OP_ILOAD */         { 2, PI_CANWIDE },
+        /* 0x16 OP_LLOAD */         { 2, PI_CANWIDE },
+        /* 0x17 OP_FLOAD */         { 2, PI_CANWIDE },
+        /* 0x18 OP_DLOAD */         { 2, PI_CANWIDE },
+        /* 0x19 OP_ALOAD */         { 2, PI_CANWIDE },
+
+        /* 0x1a OP_ILOAD_0 */       { 1, 0 },
+        /* 0x1b OP_ILOAD_1 */       { 1, 0 },
+        /* 0x1c OP_ILOAD_2 */       { 1, 0 },
+        /* 0x1d OP_ILOAD_3 */       { 1, 0 },
+        /* 0x1e OP_LLOAD_0 */       { 1, 0 },
+        /* 0x1f OP_LLOAD_1 */       { 1, 0 },
+        /* 0x20 OP_LLOAD_2 */       { 1, 0 },
+        /* 0x21 OP_LLOAD_3 */       { 1, 0 },
+        /* 0x22 OP_FLOAD_0 */       { 1, 0 },
+        /* 0x23 OP_FLOAD_1 */       { 1, 0 },
+        /* 0x24 OP_FLOAD_2 */       { 1, 0 },
+        /* 0x25 OP_FLOAD_3 */       { 1, 0 },
+        /* 0x26 OP_DLOAD_0 */       { 1, 0 },
+        /* 0x27 OP_DLOAD_1 */       { 1, 0 },
+        /* 0x28 OP_DLOAD_2 */       { 1, 0 },
+        /* 0x29 OP_DLOAD_3 */       { 1, 0 },
+        /* 0x2a OP_ALOAD_0 */       { 1, 0 },
+        /* 0x2b OP_ALOAD_1 */       { 1, 0 },
+        /* 0x2c OP_ALOAD_2 */       { 1, 0 },
+        /* 0x2d OP_ALOAD_3 */       { 1, 0 },
+
+        /* 0x2e OP_IALOAD */        { 1, 0 },
+        /* 0x2f OP_LALOAD */        { 1, 0 },
+        /* 0x30 OP_FALOAD */        { 1, 0 },
+        /* 0x31 OP_DALOAD */        { 1, 0 },
+        /* 0x32 OP_AALOAD */        { 1, 0 },
+        /* 0x33 OP_BALOAD */        { 1, 0 },
+        /* 0x34 OP_CALOAD */        { 1, 0 },
+        /* 0x35 OP_SALOAD */        { 1, 0 },
+
+        /* 0x36 OP_ISTORE */        { 2, PI_CANWIDE },
+        /* 0x37 OP_LSTORE */        { 2, PI_CANWIDE },
+        /* 0x38 OP_FSTORE */        { 2, PI_CANWIDE },
+        /* 0x39 OP_DSTORE */        { 2, PI_CANWIDE },
+        /* 0x3a OP_ASTORE */        { 2, PI_CANWIDE },
+
+        /* 0x3b OP_ISTORE_0 */      { 1, 0 },
+        /* 0x3c OP_ISTORE_1 */      { 1, 0 },
+        /* 0x3d OP_ISTORE_2 */      { 1, 0 },
+        /* 0x3e OP_ISTORE_3 */      { 1, 0 },
+        /* 0x3f OP_LSTORE_0 */      { 1, 0 },
+        /* 0x40 OP_LSTORE_1 */      { 1, 0 },
+        /* 0x41 OP_LSTORE_2 */      { 1, 0 },
+        /* 0x42 OP_LSTORE_3 */      { 1, 0 },
+        /* 0x43 OP_FSTORE_0 */      { 1, 0 },
+        /* 0x44 OP_FSTORE_1 */      { 1, 0 },
+        /* 0x45 OP_FSTORE_2 */      { 1, 0 },
+        /* 0x46 OP_FSTORE_3 */      { 1, 0 },
+        /* 0x47 OP_DSTORE_0 */      { 1, 0 },
+        /* 0x48 OP_DSTORE_1 */      { 1, 0 },
+        /* 0x49 OP_DSTORE_2 */      { 1, 0 },
+        /* 0x4a OP_DSTORE_3 */      { 1, 0 },
+        /* 0x4b OP_ASTORE_0 */      { 1, 0 },
+        /* 0x4c OP_ASTORE_1 */      { 1, 0 },
+        /* 0x4d OP_ASTORE_2 */      { 1, 0 },
+        /* 0x4e OP_ASTORE_3 */      { 1, 0 },
+
+        /* 0x4f OP_IASTORE */       { 1, 0 },
+        /* 0x50 OP_LASTORE */       { 1, 0 },
+        /* 0x51 OP_FASTORE */       { 1, 0 },
+        /* 0x52 OP_DASTORE */       { 1, 0 },
+        /* 0x53 OP_AASTORE */       { 1, 0 },
+        /* 0x54 OP_BASTORE */       { 1, 0 },
+        /* 0x55 OP_CASTORE */       { 1, 0 },
+        /* 0x56 OP_SASTORE */       { 1, 0 },
+
+        /* 0x57 OP_POP */           { 1, 0 },
+        /* 0x58 OP_POP2 */          { 1, 0 },
+
+        /* 0x59 OP_DUP */           { 1, 0 },
+        /* 0x5a OP_DUP_X1 */        { 1, 0 },
+        /* 0x5b OP_DUP_X2 */        { 1, 0 },
+        /* 0x5c OP_DUP2 */          { 1, 0 },
+        /* 0x5d OP_DUP2_X1 */       { 1, 0 },
+        /* 0x5e OP_DUP2_X2 */       { 1, 0 },
+
+        /* 0x5f OP_SWAP */          { 1, 0 },
+
+        /* 0x60 OP_IADD */          { 1, 0 },
+        /* 0x61 OP_LADD */          { 1, 0 },
+        /* 0x62 OP_FADD */          { 1, 0 },
+        /* 0x63 OP_DADD */          { 1, 0 },
+        /* 0x64 OP_ISUB */          { 1, 0 },
+        /* 0x65 OP_LSUB */          { 1, 0 },
+        /* 0x66 OP_FSUB */          { 1, 0 },
+        /* 0x67 OP_DSUB */          { 1, 0 },
+        /* 0x68 OP_IMUL */          { 1, 0 },
+        /* 0x69 OP_LMUL */          { 1, 0 },
+        /* 0x6a OP_FMUL */          { 1, 0 },
+        /* 0x6b OP_DMUL */          { 1, 0 },
+        /* 0x6c OP_IDIV */          { 1, 0 },
+        /* 0x6d OP_LDIV */          { 1, 0 },
+        /* 0x6e OP_FDIV */          { 1, 0 },
+        /* 0x6f OP_DDIV */          { 1, 0 },
+        /* 0x70 OP_IREM */          { 1, 0 },
+        /* 0x71 OP_LREM */          { 1, 0 },
+        /* 0x72 OP_FREM */          { 1, 0 },
+        /* 0x73 OP_DREM */          { 1, 0 },
+        /* 0x74 OP_INEG */          { 1, 0 },
+        /* 0x75 OP_LNEG */          { 1, 0 },
+        /* 0x76 OP_FNEG */          { 1, 0 },
+        /* 0x77 OP_DNEG */          { 1, 0 },
+        /* 0x78 OP_ISHL */          { 1, 0 },
+        /* 0x79 OP_LSHL */          { 1, 0 },
+        /* 0x7a OP_ISHR */          { 1, 0 },
+        /* 0x7b OP_LSHR */          { 1, 0 },
+        /* 0x7c OP_IUSHR */         { 1, 0 },
+        /* 0x7d OP_LUSHR */         { 1, 0 },
+        /* 0x7e OP_IAND */          { 1, 0 },
+        /* 0x7f OP_LAND */          { 1, 0 },
+        /* 0x80 OP_IOR */           { 1, 0 },
+        /* 0x81 OP_LOR */           { 1, 0 },
+        /* 0x82 OP_IXOR */          { 1, 0 },
+        /* 0x83 OP_LXOR */          { 1, 0 },
+
+        /* 0x84 OP_IINC */          { 3, PI_CANWIDE },
+
+        /* 0x85 OP_I2L */           { 1, 0 },
+        /* 0x86 OP_I2F */           { 1, 0 },
+        /* 0x87 OP_I2D */           { 1, 0 },
+        /* 0x88 OP_L2I */           { 1, 0 },
+        /* 0x89 OP_L2F */           { 1, 0 },
+        /* 0x8a OP_L2D */           { 1, 0 },
+        /* 0x8b OP_F2I */           { 1, 0 },
+        /* 0x8c OP_F2L */           { 1, 0 },
+        /* 0x8d OP_F2D */           { 1, 0 },
+        /* 0x8e OP_D2I */           { 1, 0 },
+        /* 0x8f OP_D2L */           { 1, 0 },
+        /* 0x90 OP_D2F */           { 1, 0 },
+        /* 0x91 OP_I2B */           { 1, 0 },
+        /* 0x92 OP_I2C */           { 1, 0 },
+        /* 0x93 OP_I2S */           { 1, 0 },
+
+        /* 0x94 OP_LCMP */          { 1, 0 },
+        /* 0x95 OP_FCMPL */         { 1, 0 },
+        /* 0x96 OP_FCMPG */         { 1, 0 },
+        /* 0x97 OP_DCMPL */         { 1, 0 },
+        /* 0x98 OP_DCMPG */         { 1, 0 },
+
+        /* 0x99 OP_IFEQ */          { 3, PI_JUMP },
+        /* 0x9a OP_IFNE */          { 3, PI_JUMP },
+        /* 0x9b OP_IFLT */          { 3, PI_JUMP },
+        /* 0x9c OP_IFGE */          { 3, PI_JUMP },
+        /* 0x9d OP_IFGT */          { 3, PI_JUMP },
+        /* 0x9e OP_IFLE */          { 3, PI_JUMP },
+        /* 0x9f OP_IF_ICMPEQ */     { 3, PI_JUMP },
+        /* 0xa0 OP_IF_ICMPNE */     { 3, PI_JUMP },
+        /* 0xa1 OP_IF_ICMPLT */     { 3, PI_JUMP },
+        /* 0xa2 OP_IF_ICMPGE */     { 3, PI_JUMP },
+        /* 0xa3 OP_IF_ICMPGT */     { 3, PI_JUMP },
+        /* 0xa4 OP_IF_ICMPLE */     { 3, PI_JUMP },
+        /* 0xa5 OP_IF_ACMPEQ */     { 3, PI_JUMP },
+        /* 0xa6 OP_IF_ACMPNE */     { 3, PI_JUMP },
+
+        /* 0xa7 OP_GOTO */          { 3, PI_JUMP | PI_DIRECT },
+
+        /* 0xa8 OP_JSR */           { 3, PI_JUMP},
+        /* 0xa9 OP_RET */           { 2, PI_DIRECT | PI_CANWIDE },
+
+        /* 0xaa OP_TABLESWITCH */   { 16, PI_SWITCH },
+        /* 0xab OP_LOOKUPSWITCH */  { 9, PI_SWITCH },
+
+        /* 0xac OP_IRETURN */       { 1, PI_DIRECT },
+        /* 0xad OP_LRETURN */       { 1, PI_DIRECT },
+        /* 0xae OP_FRETURN */       { 1, PI_DIRECT },
+        /* 0xaf OP_DRETURN */       { 1, PI_DIRECT },
+        /* 0xb0 OP_ARETURN */       { 1, PI_DIRECT },
+        /* 0xb1 OP_RETURN */        { 1, PI_DIRECT },
+
+        /* 0xb2 OP_GETSTATIC */     { 3, 0 },
+        /* 0xb3 OP_PUTSTATIC */     { 3, 0 },
+        /* 0xb4 OP_GETFIELD */      { 3, 0 },
+        /* 0xb5 OP_PUTFIELD */      { 3, 0 },
+
+        /* 0xb6 OP_INVOKEVIRTUAL */ { 3, 0 },
+        /* 0xb7 OP_INVOKESPECIAL */ { 3, 0 },
+        /* 0xb8 OP_INVOKESTATIC */  { 3, 0 },
+
+        /* 0xb9 OP_INVOKEINTERFACE */ { 5, 0 },
+
+        /* oxba XXX_UNUSED_XXX */   {0, 0},
+
+        /* 0xbb OP_NEW */           { 3, 0 },
+        /* 0xbc OP_NEWARRAY */      { 2, 0 },
+        /* 0xbd OP_ANEWARRAY */     { 3, 0 },
+
+        /* 0xbe OP_ARRAYLENGTH */   { 1, 0 },
+
+        /* 0xbf OP_ATHROW */        { 1, PI_DIRECT },
+
+        /* 0xc0 OP_CHECKCAST */     { 3, 0 },
+        /* 0xc1 OP_INSTANCEOF */    { 3, 0 },
+
+        /* 0xc2 OP_MONITORENTER */  { 1, 0 },
+        /* 0xc3 OP_MONITOREXIT */   { 1, 0 },
+
+        /* 0xc4 OP_WIDE */          { 2, 0 },
+
+        /* 0xc5 OP_MULTIANEWARRAY */{ 4, 0 },
+
+        /* 0xc6 OP_IFNULL */        { 3, PI_JUMP },
+        /* 0xc7 OP_IFNONNULL */     { 3, PI_JUMP },
+
+        /* 0xc8 OP_GOTO_W */        { 5, PI_JUMP | PI_DIRECT | PI_WIDEJUMP },
+        /* 0xc9 OP_JSR_W */         { 5, PI_JUMP | PI_WIDEJUMP },
+    };
+
+    /*
+    * Obtain the length of a compound instruction
+    */
+    int vf_Context_Base::instr_get_len_compound(Address instr, OpCode opcode) {
+        if( opcode == OP_WIDE ) {
+            ParseInfo &pi = instr_get_parse_info( (OpCode)m_bytecode[instr+1] );
+
+            if( !(pi.flags & PI_CANWIDE) ) {
+                // return some big value - error will occur later
+                return 0x20000123;
+            }
+
+            return 2*pi.instr_min_len;
+        }
+
+
+        Address def_adr = (instr & (~3) ) + 4;
+        if( opcode == OP_TABLESWITCH) {
+            int lowbyte = read_int32(m_bytecode + def_adr + 4);
+            int hibyte = read_int32(m_bytecode + def_adr + 8);
+
+            // protect from integer overflow
+            if( hibyte < lowbyte || hibyte - lowbyte > 0x20000000) {
+                // return some big value - error will occur later
+                return 0x20000123;
+            }
+
+            return def_adr + 12 + (hibyte - lowbyte + 1) * 4 - instr;
+        } else {
+            assert( opcode == OP_LOOKUPSWITCH );
+
+            //minimal length of OP_LOOKUPSWITCH is 9 bytes, while its required value may exceed 9 bytes, have to check bounds
+            if( (unsigned)def_adr + 8 > m_code_length ) {
+                // return some big value - error will occur later
+                return 0x20000123;
+            }
+
+            unsigned npairs = read_int32(m_bytecode + def_adr + 4);
+
+            // protect from integer overflow
+            if( npairs > 0x20000000) {
+                // return some big value - error will occur later
+                return 0x20000123;
+            }
+
+            int next = def_adr + 8;
+
+            if (npairs) {
+                int old_value = read_int32(m_bytecode + next);
+                next += 8;
+                // integer values must be sorted - verify
+                for( unsigned i = 1; i < npairs; i++) {
+                    int new_value = read_int32(m_bytecode + next);
+                    next += 8;
+                    if( old_value >= new_value ) {
+                        // return some big value - error will occur later
+                        return 0x20000123;
+                    }
+                    old_value = new_value;
+                }
+            }
+
+            return next - instr;
+        }
+    }
+
+    /*
+    * Set method constraints
+    */
+    void vf_Context_Base::set_class_constraints() {
+        if( !class_constraints ) return;
+
+        vf_ClassLoaderData_t *cl_data;
+        classloader_handler currentClassLoader = class_get_class_loader(k_class);
+
+        // lock data modification
+        cl_acquire_lock( currentClassLoader );
+        cl_data = (vf_ClassLoaderData_t*)cl_get_verify_data_ptr( currentClassLoader );
+
+        // create class loader data
+        if( cl_data == NULL ) {
+            Memory *new_pool = new Memory;
+            cl_data = (vf_ClassLoaderData_t*)new_pool->malloc(sizeof(vf_ClassLoaderData_t));
+            cl_data->pool = new_pool;
+            cl_data->hash = new vf_Hash();
+            cl_data->string = new vf_Hash();
+        }
+        Memory **pool = &cl_data->pool;
+        vf_Hash *hash = cl_data->hash;
+        vf_Hash *string = cl_data->string;
+
+        // create class hash entry
+        vf_HashEntry_t *hash_entry = hash->NewHashEntry( class_get_name( k_class ) );
+
+        for( vf_TypeConstraint *constraint = class_constraints;
+            constraint;
+            constraint = constraint->next )
+        {
+            // create new constraint
+            vf_TypeConstraint *cc = (vf_TypeConstraint*)(*pool)->malloc(sizeof(vf_TypeConstraint));
+
+            // set class constraint
+            // create hash entry for target class
+            cc->target = string->NewHashEntry( constraint->target )->key;
+            // create hash entry for checked class
+            cc->source = string->NewHashEntry( constraint->source )->key;
+
+            cc->next = (CPVerifier::vf_TypeConstraint*)hash_entry->data_ptr;
+            hash_entry->data_ptr = cc;
+        }
+
+        // unlock data modification
+        cl_set_verify_data_ptr( currentClassLoader, cl_data );
+        cl_release_lock( currentClassLoader );
+        return;
+    }
+
+} // namespace CPVerifier

Copied: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.h (from r584094, harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h)
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.h?p2=harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.h&p1=harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h&r1=584094&r2=584118&rev=584118&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/context.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/context_base.h Fri Oct 12 03:32:50 2007
@@ -17,597 +17,272 @@
 /** 
  * @author Mikhail Loenko, Vladimir Molotkov
  */  
-
-#ifndef __CONTEXT_H__
-#define __CONTEXT_H__
-
-#include <assert.h>
-#include <string.h>
-#include "verifier.h"
-#include "stackmap.h"
-#include "memory.h"
-#include "tpool.h"
-#include "instr_props.h"
-
-namespace CPVerifier {
-
-    //
-    // Context - main class of Type Checker
-    //
-
-    class vf_Context_t {
-    public:
-        vf_Context_t(class_handler _klass) :
-
-#pragma warning( push )
-#pragma warning( disable : 4355 )
-          k_class(_klass), tpool(this, 256),
-#pragma warning( pop )
-
-              constraintPool(), class_constraints(0)
-          {
-              k_major = class_get_version( _klass );
-          }
-
-          vf_Result verify_method(method_handler method);
-          void set_class_constraints();
-          Address processed_instruction;
-          int  pass;
-
-          const char *error_message;
-    protected:
-        friend class vf_TypePool;
-
-        //class handler for the current class
-		class_handler  k_class;
-
-        //major version of current class
-		unsigned short  k_major;
-
-        //method handler for the method being verified
-        method_handler m_method;
-
-        //method's bytecode
-        unsigned char  *m_bytecode;
-
-        //legth of the code in the method being verified
-        unsigned       m_code_length;
-
-        //max number of locals for the method being verified (as recorded in the classfile)
-        unsigned       m_max_locals;
-
-        //is the current method construcor (and current class in not a j.l.Object)?
-        bool           m_is_constructor;
-
-        //m_max_locals or m_max_locals+1 if it's a constructor
-        unsigned       m_stack_start;
-
-        //max stack size for the method being verified (as recorded in the classfile)
-        unsigned       m_max_stack;
-
-        //number of exception handlers for the being verified (as recorded in the classfile)
-        unsigned short m_handlecount;
-
-        //stores constraints in the classloader for reuse in vf_verify_class_constraints()
-        vf_TypeConstraint_s *class_constraints;
-
-        //storage for these constraints. class-wide
-        //TODO: makes sense to unite it with tpool containing other class-wide data?
-        Memory constraintPool;
-
-
-        /*****************/
-
-        // method's return type
-        SmConstant return_type;
-
-        // various flags for all the method's bytecode instructions
-        InstrProps props;
-
-        // table used to get various info (type, length, etc) about possible bytecode instructions
-        static ParseInfo parseTable[255];
-
-        // current set of derived types
-        WorkmapHead *workmap;
-
-        // stack to push instrauctions like branch targets, etc to go thru the method. the stack is method-wide.
-        MarkableStack stack;
-
-        FastStack dead_code_stack;
-        bool      dead_code_parsing;
-
-        static const short MARK_SUBROUTINE_DONE = -1;
-    public:
-        // basic storage for most of the method-wide data
-        Memory mem;
-    protected:
-
-        //basic storage for class-wide data, like mapping from Java classes to SmConstant types
-        vf_TypePool tpool;
-
-        /******* exception handling **********/
-
-        //flag array. if a local var i was changed by the previous instruction ==> changed_locals[i]=1, otherwise it's 0
-        byte *changed_locals;
-
-        //if there is at least one local changed
-        int locals_changed;
-
-        //if we don't know whether previous instruction changed locals (like if we are at the branch target)
-        int no_locals_info;
-
-        //number of the first handler valid for the given instruction
-        int loop_start;
-
-        //<number of the last handler valid for the given instruction> + 1
-        int loop_finish;
-
-        //start of the nearest next try block. 0 means "don't know"
-        Address next_start_pc;
-
-        /*****************/
-
-        //report verify error and store a message if any
-        vf_Result error(vf_Result result, const char* message) {
-            error_message = message ? message : "";
-            //assert(0);
-            return result;
-        }
-
-        //init method-wide data
-        void init(method_handler _m_method) {
-            //store method's parameters
-            //TODO: it might be mot slower not to store them
-            m_method = _m_method;
-            m_max_locals = method_get_max_local( m_method );
-            m_max_stack = method_get_max_stack( m_method );
-            m_code_length = method_get_code_length( m_method );
-            m_handlecount = method_get_exc_handler_number( m_method );
-            m_bytecode = method_get_bytecode( m_method );
-
-            m_is_constructor = !strcmp(method_get_name(m_method), "<init>") 
-                && class_get_super_class(k_class);
-
-            m_stack_start = m_max_locals + (m_is_constructor ? 1 : 0);
-
-            // initialize own parameters
-            mem.init();
-            props.init(mem, m_code_length);
-
-            stack.init();
-            dead_code_stack.init();
-
-            changed_locals = (byte*)mem.malloc((m_stack_start & ~3) + 4);
-
-            //to correct it later
-            return_type = SM_TOP;
-        }
-
-        // load derived types previously stored for the given instruction
-        void fill_workmap(Address instr) {
-            PropsHead *head = props.getInstrProps(instr);
-            if( head->is_workmap() ) {
-                tc_memcpy(workmap, head->getWorkmap(), sizeof(WorkmapHead) + sizeof(WorkmapElement) * (m_stack_start + head->workmap.depth));
-            } else {
-                StackmapHead *stackmap = head->getStackmap();
-
-                workmap->depth = stackmap->depth;
-
-                for( unsigned i = 0; i < m_stack_start + stackmap->depth; i++) {
-                    workmap->elements[i] = _WorkmapElement(&stackmap->elements[i]);
-                    assert( workmap->elements[i].getAnyPossibleValue() != SM_TOP );
-                }
-            }
-            no_locals_info = 1;
-        }
-
-        //store a copy of the current workmap for another instruction (such as a branch target)
-        void storeWorkmapCopy(Address target) {
-            int sz = m_stack_start + workmap->depth;
-            PropsHead* copy = newWorkmap(sz);
-            tc_memcpy(copy->getWorkmap(), workmap, sizeof(WorkmapHead) + sizeof(WorkmapElement) * sz);
-
-            props.setInstrProps(target, copy);
-        }
-
-        //create a stackmap vector of the given size sz (max_locals <= sz <= max_locals+max_stack)
-        PropsHead* newStackmap(int sz) {
-            return (PropsHead*)mem.calloc(sizeof(PropsHead) + sizeof(StackmapElement) * sz);
-        }
-
-        //create a workmap vector for the given size sz (max_locals <= sz <= max_locals+max_stack)
-        PropsHead *newWorkmap(int sz) {
-            PropsHead * ret = (PropsHead*)mem.malloc(sizeof(PropsHead) + sizeof(WorkmapElement) * sz);
-            ret->set_as_workmap();
-            return ret;
-        }
-
-        //create a vector that will be used for JSR procesing. 
-        //It contains ether stackmap or workmap vector, SubrouitineData, and flags vector indicating 
-        //changed locals
-        PropsHead *newRetData() {
-            assert( sizeof(StackmapElement) >= sizeof(WorkmapElement) );
-
-            int sz = sizeof(PropsHead) + sizeof(StackmapElement) * (m_max_stack + m_stack_start) + //stackmap
-                ((sizeof(SubroutineData)+ m_stack_start) & (~3)) + 4; // fixed data and changed locals vector
-
-            PropsHead * ret = (PropsHead *) mem.calloc(sz);
-            ret->set_as_workmap();
-            return ret;
-        }
-
-        //creates a temporary variable for converting 
-        StackmapElement *new_variable() {
-            return (StackmapElement *)mem.calloc(sizeof(StackmapElement));
-        }
-
-        /////////////////////////////////////////////////////////////////////////////////////////////////////
-
-        //First verification pass thru the method. checks that no jump outside the method or to the middle of instruction
-        //checks that opcodes are valid
-        vf_Result parse(Address instr);
-
-        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
-        //on return, athrow or hitting previously passed instruction. 
-        //This function initializes workmap and calls DataflowLoop
-        vf_Result StartLinearDataflow(Address start);
-
-        //Second pass: Finilize subroutie processing -- once we are here, then all the RETs from achievable for
-        //the given subroutine are passed, so we can resume passing for JSRs to the given address
-        //This function initializes workmap properly and calls DataflowLoop
-        vf_Result SubroutineDone(Address start);
-
-        //Second pass: dataflow of a piece of the method starting from the beginning or a branch target and finishing
-        //on return, athrow or hitting previously passed instruction
-        vf_Result DataflowLoop(Address start, int workmap_is_a_copy_of_stackmap);
-
-        //Second pass: check type-safety of a single instruction
-        vf_Result dataflow_instruction(Address instr);
-
-        //Second pass: check type-safety for exception handlers of a single instruction
-        vf_Result dataflow_handlers(Address instr);
-
-        //specail care for <init> calls is in try blocks
-        vf_Result propagate_bogus_to_handlers(Address instr, SmConstant uninit_value);
-
-        //create constraint vector in case of a branch 
-        //simple conatraints are created for pairs of both locals and stack (current must be assignable to target)
-        vf_Result new_generic_vector_constraint(Address target);
-
-        //create constraint vector for exception handler
-        //simple conatraints are created for pairs of local variable (current must be assignable to start of exception handler)
-        vf_Result new_handler_vector_constraint(Address handler);
-
-        //create simple single constraint: "'from' is assingable to 'to'"
-        vf_Result new_scalar_constraint(WorkmapElement *from, StackmapElement *to);
-
-        //create special type of conatraint: "'from' is an array and it's element is assignable to 'to'"
-        vf_Result new_scalar_array2ref_constraint(WorkmapElement *from, WorkmapElement *to);
-
-        //constraint propagation
-        vf_Result propagate(StackmapElement *changed, SmConstant new_value);
-
-        //update current derived types according to what was changed in subroutine
-        void restore_workmap_after_jsr(Address jsr_target);
-
-        //when we hit RET instruction we update the data for the given subroutine with current derived types
-        vf_Result new_ret_vector_constraint(Address target_instr);
-
-        /////////////////////////////////////////////////////////////////////////////////////////////////////
-
-        //check conditions for accessing protected non-static fields in different package
-        vf_Result popFieldRef(SmConstant expected_ref, unsigned short cp_idx);
-
-        //check conditions for accessing protected virtual methods in different package
-        vf_Result popVirtualRef(SmConstant expected_ref, unsigned short cp_idx);
-
-        /////////////////////////////////////////////////////////////////////////////////////////////////////
-
-        //add one more possible value (type) that can come to the given point (local or stack)
-        vf_Result add_incoming_value(SmConstant new_value, StackmapElement *destination);
-
-        //returns stackmap for the 'instr' instruction
-        //if it does not exists yet -- create it. When created use 'depth' as stack depth
-        StackmapHead *getStackmap(Address instr, int depth) {
-            PropsHead *pro = props.getInstrProps(instr);
-            if( !pro ) {
-                pro = newStackmap(m_stack_start + depth);
-                props.setInstrProps(instr, pro);
-                pro->getStackmap()->depth = depth;
-            }
-            return pro->getStackmap();
-        }
-
-        //create stackmap for exception handler start
-        void createHandlerStackmap(Address handler_pc, SmConstant type) {
-            StackmapHead *map = getStackmap(handler_pc, 1);
-            //handler stackmaps are created before any dataflow analysis is done
-            assert(map->depth == 0 || map->depth == 1);
-            map->depth = 1;
-
-            vf_Result tcr = add_incoming_value(type, &map->elements[m_stack_start]);
-
-            // it is initialization stage
-            assert(tcr == VF_OK);
-        }
-
-
-        /////////////// set, get locals; push, pop stack; check... //////////////
-
-        //when exercizing instructions: POP operand from the stack
-        WorkmapElement workmap_pop() {
-            assert( workmap_can_pop(1) );
-            return workmap->elements[ (--workmap->depth) + m_stack_start ];
-        }
-
-        //looking the operand stack
-        WorkmapElement workmap_stackview(int depth) {
-            assert( depth >= 0 && workmap_can_pop(depth+1) );
-            return workmap->elements[ workmap->depth + m_stack_start - depth - 1];
-        }
-
-        //when exercizing instructions: PUSH operand to the stack
-        void workmap_push(WorkmapElement el) {
-            assert( workmap_can_push(1) );
-            workmap->elements[ (workmap->depth++) + m_stack_start ] = el;
-        }
-
-        //when exercizing instructions: PUSH a const (known) type to the stack (except long and double)
-        void workmap_push_const(SmConstant value) {
-            assert( workmap_can_push(1) );
-            workmap->elements[ workmap->depth + m_stack_start ] = _WorkmapElement(value);
-            workmap->depth++;
-        }
-
-        //when exercizing instructions: PUSH a const (known) long or double type to the stack
-        void workmap_2w_push_const(SmConstant value) {
-            workmap_push_const(SM_HIGH_WORD);
-            workmap_push_const(value);
-        }
-
-        //when exercizing instructions: check if the local idx is valid for long and double
-        bool workmap_valid_2w_local(unsigned idx) {
-            return workmap_valid_local(idx + 1);
-        }
-
-        //when exercizing instructions: check if the local idx is valid (except long and double)
-        bool workmap_valid_local(unsigned idx) {
-            return idx < m_max_locals;
-        }
-
-        //get local type by idx
-        WorkmapElement workmap_get_local(unsigned idx) {
-            assert( workmap_valid_local(idx) );
-            return workmap->elements[ idx ];
-        }
-
-        //set local type
-        void workmap_set_local(unsigned idx, WorkmapElement &el) {
-            assert( workmap_valid_local(idx) );
-
-            changed_locals[ idx ] = 1;
-            locals_changed = true;
-
-            el.setJsrModified();
-            workmap->elements[ idx ] = el;		
-        }
-
-        //set local to a const (known) type except long and double
-        void workmap_set_local_const(unsigned idx, SmConstant value) {
-            assert( workmap_valid_local(idx) );
-
-            changed_locals[ idx ] = 1;
-            locals_changed = true;
-
-            workmap->elements[idx] = _WorkmapElement(value);
-
-            //don't need to set "jsr modified" flag for constants
-            //because they are already odd
-            assert(workmap->elements[idx].isJsrModified());
-        }                                                              
-
-        //set local to a const (known) long or double type
-        void workmap_set_2w_local_const(unsigned idx, SmConstant value) {
-            assert( workmap_valid_2w_local(idx) );
-            workmap_set_local_const(idx + 1, value);
-            workmap_set_local_const(idx, SM_HIGH_WORD);
-        }
-
-        //check whether we can pop 'number' elements from the operand stack
-        int workmap_can_pop(unsigned number) {
-            return workmap->depth >= number;
-        }
-
-        //check whether we can push 'number' elements to the operand stack
-        int workmap_can_push(unsigned number) {
-            return workmap->depth + number <= m_max_stack;
-        }
-
-        /////////////// expect some type //////////////
-
-        //expect exactly this type (or SM_TOP)
-        int workmap_expect_strict( WorkmapElement &el, SmConstant type ) {
-            assert(type != SM_BOGUS);
-
-            if( !el.isVariable() ) {
-                return type == el.getConst();
-            }
-
-            IncomingType *in = el.getVariable()->firstIncoming();
-            while( in ) {
-                if( type != in->value ) {
-                    return false;
-                }
-                in = in->next();
-            }
-
-            ExpectedType *exp = el.getVariable()->firstExpected();
-            while( exp ) {
-                if( type == exp->value ) {
-                    return true;
-                }
-                exp = exp->next();
-            }
-
-            el.getVariable()->newExpectedType(&mem, type);
-
-            return true;
-        }
-
-        int workmap_expect( WorkmapElement &el, SmConstant type ) {
-            if( !el.isVariable() ) {
-                return tpool.mustbe_assignable(el.getConst(), type);
-            } else {
-                ExpectedType* exp = el.getVariable()->firstExpected();
-                while( exp ) {
-                    if( type == exp->value ) {
-                        return true;
-                    }
-                    exp = exp->next();
-                }
-
-                IncomingType *in = el.getVariable()->firstIncoming();
-                //check that all existing incoming type are assignable to the new expected type
-                while( in ) {
-                    if( !tpool.mustbe_assignable(in->value, type) ) {
-                        return false;
-                    }
-                    in = in->next();
-                }
-                //add the new expected type
-                el.getVariable()->newExpectedType(&mem, type);
-            }
-            return true;
-        }
-
-        vf_Result create_method_initial_workmap();
-
-
-        //////////////// get constant SM_ELEMENTs ///////////////////////
-
-        //for given uninit_value create SmConstant for initialized value
-        //this function is used when <init>s and invoked
-        SmConstant sm_convert_to_initialized(SmConstant uninit_value) {
-            if( uninit_value == SM_THISUNINIT ) {
-                return tpool.sm_get_const_this();
-            }
-
-            if( uninit_value.isNewObject() ) {
-                Address addr = uninit_value.getNewInstr();
-
-                unsigned cp_idx = read_int16(m_bytecode + addr + 1);
-                SmConstant new_type;
-                if( !tpool.cpool_get_class(cp_idx, &new_type) ) {
-                    assert(0);
-                    return SM_BOGUS;
-                }
-                return new_type;
-            }
-
-            assert(0);
-            return SM_BOGUS;
-        }
-
-        //create vector constraints for each target of a switch
-        vf_Result processSwitchTarget(Address target) {
-            vf_Result tcr;
-            if( props.isMultiway(target) ) {
-                if( (tcr=new_generic_vector_constraint(target)) != VF_OK ) {
-                    return tcr;
-                }
-
-                if( !props.isDataflowPassed(target) ) {
-                    stack.xPush(target);
-                }
-            } else {
-                assert( !props.isDataflowPassed(target) );
-                storeWorkmapCopy(target);
-
-                stack.xPush(target);
-            }
-            return VF_OK;
-        }
-
-        /////////////////////// convinient methods //////////////////////////////////////////
-
-        //get length of variable size instruction (WIDE, *SWITCH)
-        int instr_get_len_compound(Address instr, OpCode opcode);
-
-        //read two-byte value
-        static uint16 read_int16(byte* ptr) {
-            return (ptr[0] << 8) | ptr[1];
-        }
-
-        //read four-byte value
-        static uint32 read_int32(byte* ptr) {
-            return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
-        }
-
-        //get properties specific for the given opcode
-        static ParseInfo &instr_get_parse_info(OpCode opcode) {
-            return parseTable[opcode];
-        }
-
-        //get the length of the given instruction or minimal length if unknown
-        static byte instr_get_minlen(ParseInfo &pi) {
-            return pi.instr_min_len;
-        }
-
-        //whether this instruction GOTO, IF*, or JSR
-        static int instr_is_jump(ParseInfo &pi) {
-            return pi.flags & PI_JUMP;
-        }
-
-        //whether this instruction GOTO, RETURN, ATHROW, or RET
-        static int instr_direct(ParseInfo &pi, OpCode opcode, byte* code, Address instr) {
-            return (pi.flags & PI_DIRECT) || (opcode == OP_WIDE && code[instr + 1] == OP_RET);
-        }
-
-        //whether this instruction a *SWITCH
-        static int instr_is_switch(ParseInfo &pi) {
-            return pi.flags & PI_SWITCH;
-        }
-
-        //other types of instructions
-        static int instr_is_regular(ParseInfo &pi) {
-            return !(pi.flags & (PI_SWITCH|PI_JUMP|PI_DIRECT));
-        }
-
-        //whether instruction length is unknown
-        static int instr_is_compound(OpCode opcode, ParseInfo &pi) {
-            return (pi.flags & PI_SWITCH) || opcode == OP_WIDE;
-        }
-
-        //JSR ?
-        static int instr_is_jsr(OpCode opcode) {
-            return opcode == OP_JSR || opcode == OP_JSR_W;
-        }
-
-        //RET ?
-        static int instr_is_ret(OpCode opcode, byte* code, Address instr) {
-            return opcode == OP_RET || opcode == OP_WIDE && code[instr + 1] == OP_RET;
-        }
-
-        //return the jump target for the given instruction
-        static Address instr_get_jump_target(ParseInfo &pi, byte* code, Address instr) {
-            if( pi.flags & PI_WIDEJUMP ) {
-                return instr + read_int32(code + instr + 1);
-            } else {
-                return instr + read_int16(code + instr + 1);
-            }        
-        }
-
-        //is this opcode valid?
-        static int instr_is_valid_bytecode(OpCode opcode) {
-            return opcode <= OP_MAXCODE && opcode != OP_XXX_UNUSED_XXX;
-        }
-    };
-
-    //check conatraints stored in the classloader data. force loading if necessary
-    vf_Result
-        vf_force_check_constraint(class_handler klass,
-        vf_TypeConstraint_t *constraint);
-
-} // namespace CPVerifier
-
-#endif
+
+#ifndef __CONTEXT_BASE_H__
+#define __CONTEXT_BASE_H__
+
+#include <assert.h>
+#include <string.h>
+#include "verifier.h"
+#include "memory.h"
+#include "instr_props.h"
+#include "tpool.h"
+
+namespace CPVerifier {
+
+
+    class SharedClasswideData {
+    public:
+        SharedClasswideData(class_handler _klass) :
+          class_constraints(0),
+              k_class(_klass),
+              k_major(class_get_version(_klass)),
+#pragma warning( push )
+#pragma warning( disable : 4355 )
+              tpool(this, _klass, 256)
+#pragma warning( pop )
+          {}
+
+          //basic storage for class-wide data, like mapping from Java classes to SmConstant types
+          vf_TypePool tpool;
+
+          //stores constraints in the classloader for reuse in vf_verify_class_constraints()
+          vf_TypeConstraint *class_constraints;
+
+          //storage for these constraints. class-wide
+          Memory constraintPool;
+
+          //class handler for the current class
+          class_handler  k_class;
+
+          //major version of current class
+          unsigned short  k_major;
+
+          //below are actually not shared between differetn methods, 
+          //we define large-size variables here to save stack footprint
+
+          // basic storage for most of the method-wide data
+          Memory mem;
+    };
+
+
+    //
+    // Context - main class of Type Checker
+    //
+
+    class vf_Context_Base {
+    public:
+        vf_Context_Base(SharedClasswideData &_classwide) :
+
+            classwide(_classwide), class_constraints(_classwide.class_constraints), 
+            mem(_classwide.mem), constraintPool(_classwide.constraintPool), tpool(_classwide.tpool),
+            k_class(_classwide.k_class), k_major(classwide.k_major)
+        {}
+
+        //current instruction - used for error message creation
+        Address processed_instruction;
+
+        //pass (in case if Java5 verification) - used for error message creation
+        int  pass;
+
+        //error message in case of unsuccessful verification
+        const char *error_message;
+
+        //store ref to classwide data
+        SharedClasswideData &classwide;
+
+        //store constraints on unloaded classes for later verification
+        void set_class_constraints();
+    protected:
+        friend class vf_TypePool;
+
+        //class handler for the current class
+        class_handler  k_class;
+
+        //major version of current class
+        unsigned short  k_major;
+
+        //method handler for the method being verified
+        method_handler m_method;
+
+        //method's bytecode
+        unsigned char  *m_bytecode;
+
+        //legth of the code in the method being verified
+        unsigned       m_code_length;
+
+        //max number of locals for the method being verified (as recorded in the classfile)
+        unsigned       m_max_locals;
+
+        //is the current method construcor (and current class in not a j.l.Object)?
+        bool           m_is_constructor;
+
+        //m_max_locals or m_max_locals+1 if it's a constructor
+        unsigned       m_stack_start;
+
+        //max stack size for the method being verified (as recorded in the classfile)
+        unsigned       m_max_stack;
+
+        //number of exception handlers for the being verified (as recorded in the classfile)
+        unsigned short m_handlecount;
+
+        //stores constraints in the classloader for reuse in vf_verify_class_constraints()
+        vf_TypeConstraint_p &class_constraints;
+
+        //storage for these constraints. class-wide
+        //TODO: makes sense to unite it with tpool containing other class-wide data?
+        Memory &constraintPool;
+
+        // basic storage for most of the method-wide data
+        Memory &mem;
+
+        // table used to get various info (type, length, etc) about possible bytecode instructions
+        static ParseInfo parseTable[255];
+
+        // method's return type
+        SmConstant return_type;
+
+        //basic storage for class-wide data, like mapping from Java classes to SmConstant types
+        vf_TypePool &tpool;
+
+        /******* exception handling **********/
+
+        //flag array. if a local var i was changed by the previous instruction ==> changed_locals[i]=1, otherwise it's 0
+        uint8 *changed_locals;
+
+        //if there is at least one local changed
+        int locals_changed;
+
+        //if we don't know whether previous instruction changed locals (like if we are at the branch target)
+        int no_locals_info;
+
+        //number of the first handler valid for the given instruction
+        int loop_start;
+
+        //<number of the last handler valid for the given instruction> + 1
+        int loop_finish;
+
+        //start of the nearest next try block. 0 means "don't know"
+        Address next_start_pc;
+
+        /*****************/
+
+        //report verify error and store a message if any
+        vf_Result error(vf_Result result, const char* message) {
+            //PUT BREAKPOINT HERE!!!
+            error_message = message ? message : "";
+            //assert(0);
+            return result;
+        }
+
+        //init method-wide data
+        void init(method_handler _m_method) {
+            //store method's parameters
+            //TODO: it might be mot slower not to store them
+            m_method = _m_method;
+            m_max_locals = method_get_max_local( m_method );
+            m_max_stack = method_get_max_stack( m_method );
+            m_code_length = method_get_code_length( m_method );
+            m_handlecount = method_get_exc_handler_number( m_method );
+            m_bytecode = method_get_bytecode( m_method );
+
+            m_is_constructor = !strcmp(method_get_name(m_method), "<init>") 
+                && class_get_super_class(k_class);
+
+            m_stack_start = m_max_locals + (m_is_constructor ? 1 : 0);
+
+            // initialize own parameters
+            mem.init();
+
+            changed_locals = (uint8*)mem.malloc((m_stack_start & ~3) + 4);
+
+            //to correct it later
+            return_type = SM_NONE;
+        }
+
+
+        /////////////////////// convinient methods //////////////////////////////////////////
+
+        //get length of variable size instruction (WIDE, *SWITCH)
+        int instr_get_len_compound(Address instr, OpCode opcode);
+
+        //read two-byte value
+        static uint16 read_int16(uint8* ptr) {
+            return (ptr[0] << 8) | ptr[1];
+        }
+
+        //read four-byte value
+        static uint32 read_int32(uint8* ptr) {
+            return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
+        }
+
+        //get properties specific for the given opcode
+        static ParseInfo &instr_get_parse_info(OpCode opcode) {
+            return parseTable[opcode];
+        }
+
+        //get the length of the given instruction or minimal length if unknown
+        static uint8 instr_get_minlen(ParseInfo &pi) {
+            return pi.instr_min_len;
+        }
+
+        //whether this instruction GOTO, IF*, or JSR
+        static int instr_is_jump(ParseInfo &pi) {
+            return pi.flags & PI_JUMP;
+        }
+
+        //whether this instruction GOTO, RETURN, ATHROW, or RET
+        static int instr_direct(ParseInfo &pi, OpCode opcode, uint8* code, Address instr) {
+            return (pi.flags & PI_DIRECT) || (opcode == OP_WIDE && code[instr + 1] == OP_RET);
+        }
+
+        //whether this instruction a *SWITCH
+        static int instr_is_switch(ParseInfo &pi) {
+            return pi.flags & PI_SWITCH;
+        }
+
+        //other types of instructions
+        static int instr_is_regular(ParseInfo &pi) {
+            return !(pi.flags & (PI_SWITCH|PI_JUMP|PI_DIRECT));
+        }
+
+        //whether instruction length is unknown
+        static int instr_is_compound(OpCode opcode, ParseInfo &pi) {
+            return (pi.flags & PI_SWITCH) || opcode == OP_WIDE;
+        }
+
+        //JSR ?
+        static int instr_is_jsr(OpCode opcode) {
+            return opcode == OP_JSR || opcode == OP_JSR_W;
+        }
+
+        //RET ?
+        static int instr_is_ret(OpCode opcode, uint8* code, Address instr) {
+            return opcode == OP_RET || opcode == OP_WIDE && code[instr + 1] == OP_RET;
+        }
+
+        //return the jump target for the given instruction
+        static Address instr_get_jump_target(ParseInfo &pi, uint8* code, Address instr) {
+            if( pi.flags & PI_WIDEJUMP ) {
+                return instr + read_int32(code + instr + 1);
+            } else {
+                return instr + read_int16(code + instr + 1);
+            }        
+        }
+
+        //is this opcode valid?
+        static int instr_is_valid_bytecode(OpCode opcode) {
+            return opcode <= OP_MAXCODE && opcode != OP_XXX_UNUSED_XXX;
+        }
+
+    };
+
+
+    //check conatraints stored in the classloader data. force loading if necessary
+    vf_Result
+        vf_force_check_constraint(class_handler klass,
+        vf_TypeConstraint *constraint);
+
+} // namespace CPVerifier
+
+#endif



Mime
View raw message