harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mloe...@apache.org
Subject svn commit: r584170 [4/7] - in /harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363: base/ java5/ java6/
Date Fri, 12 Oct 2007 14:42:23 GMT
Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp Fri Oct 12 07:42:03 2007
@@ -1,586 +1,586 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-#include <assert.h>
-#include "tpool.h"
-#include "context_base.h"
-
-namespace CPVerifier {
-
-    vf_TypePool::vf_TypePool(SharedClasswideData *_classwide, class_handler _klass, unsigned table_incr)
-        : classwide(_classwide), tableIncr(table_incr),
-        validTypesTableMax(0), validTypesTableSz(1), validTypes(0)
-    {
-        const_object = const_class = const_string = const_throwable = const_arrayref_of_bb =
-            const_arrayref_of_char = const_arrayref_of_double = const_arrayref_of_float =
-            const_arrayref_of_integer = const_arrayref_of_long = const_arrayref_of_short = 
-            const_arrayref_of_object = const_this = SM_NONE;
-
-        k_class = _klass;
-        k_cp_length = class_get_cp_size( k_class );
-    }
-
-    /*
-    * Returns name length if it is array of boolean or 0
-    */
-    inline int vf_TypePool::is_bool_array_conv_needed(const char *type_name, int length) {
-        return length > 1 && type_name[length - 1] == 'Z' && type_name[length - 2] == '[';
-    }
-
-    /*
-    * Get SmConstant by type name.
-    */
-    SmConstant vf_TypePool::get_ref_type(const char *type_name, int length) {
-        //TODO: this assert raise false alarms when type name starts with 'L'
-        //assert(type_name[0] != 'L');
-
-        // find type in hash
-        vf_HashEntry_t *entry = hash.NewHashEntry( type_name, length );
-        unsigned index = entry->data_index;
-        if( !index ) {
-            //convert array of booleans to array of bytes
-            if( is_bool_array_conv_needed(type_name, length) ) {
-                char *new_name = (char*)classwide->mem.malloc(length+1);
-                tc_memcpy(new_name, type_name, length);
-                new_name[length-1] = 'B';
-                index = get_ref_type(new_name, length).getReferenceIdx();
-                classwide->mem.dealloc_last(new_name, length+1);
-            }
-            // Get next free table entry index
-            if( !index ) {
-                index = check_table();
-                validTypes[index].cls = 0;
-                validTypes[index].name = entry->key;
-            }
-            entry->data_index = index;
-        }
-
-        assert(index < validTypesTableSz);
-        return SmConstant::getReference(index);
-    }
-
-    SmConstant vf_TypePool::get_primitive_type(const char type_char) {
-        switch( type_char ) {
-        case 'I':
-        case 'B':
-        case 'Z':
-        case 'C':
-        case 'S':
-            return SM_INTEGER;
-        case 'J':
-            return SM_LONG;
-        case 'F':
-            return SM_FLOAT;
-        case 'V':
-            return SM_BOGUS;
-        case 'D':
-            return SM_DOUBLE;
-        default:
-            assert(0);
-            return SM_BOGUS;
-        }
-    }
-
-    SmConstant vf_TypePool::get_type(const char *type_name, int name_len) {
-        if( name_len > 1 ) {
-            if( type_name[0] == '[' ) {
-                return get_ref_type(type_name, name_len);
-            }
-
-            if( type_name[0] == 'L' ) {
-                return get_ref_type(type_name + 1, name_len - 2);
-            }
-
-            return SM_BOGUS;
-        } else {
-            return get_primitive_type(type_name[0]);
-        }
-    }
-
-
-    SmConstant vf_TypePool::get_ref_from_array(SmConstant element) {
-        if( element == SM_NULL ) return SM_NULL;
-
-        assert(element.isReference());
-        assert(sm_get_refname(element)[0] == '[');
-        return get_type(sm_get_refname(element) + 1);
-    }
-
-
-    int vf_TypePool::mustbe_assignable(SmConstant from, SmConstant to) {
-        if( from == to || to == SM_NONE || to == SM_BOGUS ) return true;
-        if( from == SM_BOGUS ) return false;
-
-        if( to.isReference() ) {
-            if( from == SM_NULL ) return true;
-
-            if( from.isReference() ) {
-                return ref_mustbe_assignable(from, to);
-            }
-
-            return false;
-        }
-
-        if( !to.isPrimitive() ) {
-            assert( to != from ); // checked above
-            return false;
-        }
-
-        //migth have to change switch below if merging is done with constants
-        assert( from != SM_NONE );
-        assert( from != SM_ONEWORDED );
-        assert( from != SM_REF_OR_UNINIT_OR_RETADR );
-        assert( from != SM_REF_OR_UNINIT );
-        assert( from != SM_ANYARRAY );
-        assert( from != SM_BOGUS );
-
-        switch ( to.c ) {
-        case SM_ONEWORDED:
-            return !from.isLongOrDouble();
-
-        case SM_REF_OR_UNINIT_OR_RETADR:
-            return from == SM_NULL || from == SM_THISUNINIT || !from.isPrimitive();
-
-        case SM_REF_OR_UNINIT:
-            return from == SM_NULL || from == SM_THISUNINIT || from.isNewObject() || from.isReference();
-
-        case SM_ANYARRAY:
-            return from == SM_NULL || from.isReference() && sm_get_refname(from)[0] == '[';
-
-        case SM_NULL:
-        case SM_THISUNINIT:
-            assert(0);
-            return false;
-
-        case SM_HIGH_WORD:
-        case SM_INTEGER:
-        case SM_FLOAT:
-        case SM_LONG:
-        case SM_DOUBLE:
-        case SM_BOGUS:
-            return false;
-        default:
-            assert(0);
-            return false;
-        }
-    }
-
-    int vf_TypePool::ref_mustbe_assignable(SmConstant from, SmConstant to) {
-        if( to == sm_get_const_object() ) return true;
-
-        vf_ValidType *to_type = getVaildType(to.getReferenceIdx());
-        vf_ValidType *from_type = getVaildType(from.getReferenceIdx());
-
-        const char *to_name = to_type->name;
-        const char *from_name = from_type->name;
-
-        int to_array = to_name[0] == '[';
-        int from_array = from_name[0] == '[';
-
-        if( to_array && !from_array ) {
-            return false;
-        } else if( to_array && from_array ) {
-            int dim = 0;
-            while( to_name[dim] == '[' && from_name[dim] == '[' ) dim++;
-
-            if( from_name[dim] != 'L' && from_name[dim] != '[' ) {
-                //primitive type
-                dim--;
-            }
-
-            if( to_name[dim] != 'L' ) return false;
-
-            if( from_name[dim] == 'L' ) {
-                //merge refs
-                return ref_mustbe_assignable(get_type(from_name + dim), get_type(to_name + dim) );
-            } else {
-                //to must be Object or an interface
-                return ref_mustbe_assignable(sm_get_const_object(), get_type(to_name + dim) );
-            }
-        } else if( from_array ) {
-            //from is an array, to is not an array
-
-            //must be checked before
-            assert( from != to );
-
-            return to == sm_get_const_object() || !strcmp(to_name, "java/lang/Cloneable") || 
-                    !strcmp(to_name, "java/io/Serializable");
-        } else {
-            //both not arrays
-
-            //check whether TO class is loaded
-            if( !to_type->cls ) {
-                to_type->cls = vf_resolve_class(k_class, to_type->name, false);
-                if( !to_type->cls ) to_type->cls = CLASS_NOT_LOADED;
-            }
-
-            if( to_type->cls && to_type->cls != CLASS_NOT_LOADED ) {
-                //if to is loaded and it is an interface, treat it as an object
-                if( class_is_interface_( to_type->cls ) ) {
-                    return true;
-                }
-            } else {
-                NewConstraint(from_type->name, to_type->name);
-                return true;
-            }
-
-            //check whether FROM class is loaded
-            if( !from_type->cls ) {
-                from_type->cls = vf_resolve_class(k_class, from_type->name, false);
-                if( !from_type->cls ) from_type->cls = CLASS_NOT_LOADED;
-            }
-
-            if( from_type->cls && from_type->cls != CLASS_NOT_LOADED ) {
-                return vf_is_extending(from_type->cls, to_type->cls);
-            } else {
-                NewConstraint(from_type->name, to_type->name);
-                return 1;
-            }
-        }
-    }
-
-    //check if expected_ref is a super class of 'this', its package differs
-    int vf_TypePool::checkSuperAndPackage(SmConstant expected_ref) {
-        //check that expected ref is a super of 'this'
-        vf_ValidType *expected_type = getVaildType(expected_ref.getReferenceIdx());
-        class_handler &referred = expected_type->cls;
-
-        if( !referred ) {
-            //try to get class
-            referred = vf_resolve_class(k_class, expected_type->name, false);
-
-            if( !referred ) {
-                referred = CLASS_NOT_LOADED;
-            }
-        }
-
-        if( referred == CLASS_NOT_LOADED ) {
-            //referred class can't be resolved ==> it's not a super class
-//#ifndef NDEBUG
-//            class_handler k = k_class;
-//            while(k) {
-//                assert(strcmp(class_get_name(k), expected_type->name));
-//                k = class_get_super_class(k);
-//            }
-//#endif
-            return false;
-        }
-
-        return !class_is_same_package(k_class, referred) && vf_is_extending(k_class, referred);
-    }
-
-    //check if expected_ref is a super class of 'this', its package differs, and it's protected
-    int vf_TypePool::checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx) {
-        //check if expected_ref is a super class of 'this', its package differs
-        if( !checkSuperAndPackage(expected_ref) ) {
-            return _FALSE;
-        }
-
-        //check further
-        //check that they are in different packages and method is protected
-        method_handler method = class_resolve_method(k_class, method_idx);
-
-        if (!method || method_is_static(method)) {
-            //it's not a VerifyError
-            return _FALSE;
-        }
-        
-        // for arrays function clone is public
-        return !method_is_protected(method) ? _FALSE : !memcmp(method_get_name(method), "clone", 6) ? _CLONE : _TRUE;
-    }
-
-    //check if expected_ref is a super class of 'this', its package differs, and it's protected
-    int vf_TypePool::checkFieldAccess(SmConstant expected_ref, unsigned short field_idx) {
-        //check if expected_ref is a super class of 'this', its package differs
-        if( !checkSuperAndPackage(expected_ref) ) {
-            return _FALSE;
-        }
-
-        //check further
-        //check that they are in different packages and method is protected
-        field_handler field = class_resolve_nonstatic_field(k_class, field_idx);
-
-        if (!field) {
-            //it's not a VerifyError
-            return _FALSE;
-        }
-        
-        // for arrays function clone is public
-        return field_is_protected(field) ? _TRUE : _FALSE;
-    }
-
-
-    void vf_TypePool::NewConstraint(const char *available,
-        const char *required)
-    {
-        vf_TypeConstraint *constraint;
-
-        // lookup constraint
-        for( constraint = classwide->class_constraints; constraint; constraint = constraint->next) {
-            if( constraint->target == required && constraint->source == available ) {
-                // this constraint is already present
-                return;
-            }
-        }
-
-        // set constraint
-        constraint = (vf_TypeConstraint*)classwide->constraintPool.malloc(sizeof(vf_TypeConstraint));
-        constraint->target = required;
-        constraint->source = available;
-        constraint->next = classwide->class_constraints;
-        classwide->class_constraints = constraint;
-
-        return;
-    }
-
-    SmConstant vf_TypePool::cpool_get_ldcarg(unsigned short cp_idx) {
-        if( cp_idx >= k_cp_length || !cp_idx ) return SM_BOGUS;
-
-        switch (class_get_cp_tag( k_class, cp_idx ) ) {
-        case _CONSTANT_String: 
-            return sm_get_const_string();
-
-        case _CONSTANT_Integer: 
-            return SM_INTEGER;
-
-        case _CONSTANT_Float:
-            return SM_FLOAT;
-
-        case _CONSTANT_Class:
-            //check if it's a 1.5 class (major version is 49)
-            return classwide->k_major < 49 ? SM_BOGUS : sm_get_const_class();
-
-        default:
-            return SM_BOGUS;
-        }
-    }
-
-
-    SmConstant vf_TypePool::cpool_get_ldc2arg(unsigned short cp_idx) {
-        if( cp_idx >= k_cp_length || !cp_idx ) return SM_BOGUS;
-
-        switch (class_get_cp_tag( k_class, cp_idx ) ) {
-        case _CONSTANT_Double: 
-            return SM_DOUBLE;
-
-        case _CONSTANT_Long: 
-            return SM_LONG;
-
-        default:
-            return SM_BOGUS;
-        }
-    }
-
-
-    int vf_TypePool::cpool_is_reftype(unsigned short cp_idx) {
-        return cp_idx && cp_idx < k_cp_length && class_get_cp_tag( k_class, cp_idx ) == _CONSTANT_Class;
-    }
-
-
-    int vf_TypePool::cpool_get_class(unsigned short cp_idx, SmConstant *ref, int expected_dim) {
-        if( !cpool_is_reftype(cp_idx) ) return false;
-
-        unsigned short name_idx = class_get_cp_class_name_index(k_class, cp_idx);
-        if( name_idx >= k_cp_length ) return false;
-
-        const char* name = class_get_cp_utf8_bytes( k_class, name_idx );
-
-        //validate dimensions
-        int ptr = 0;
-        while (name[ptr] == '[' ) {
-            ptr++;
-        }
-        //'name' already contains final '[', so max dimension of class 'name' is 255
-        if( ptr <  expected_dim || ptr > 255 ) return false;
-
-        //array is not allowed here
-        if( ptr && expected_dim == -1 ) return false;
-
-
-        //TODO: do we need to resolve if we don't need SmConstant?
-        //e.g. do we need to resolve class of a static variable?
-        //constantpool validation should be done whereever else
-        if( ref ) *ref = get_ref_type(name, (int)strlen(name));
-
-        return true;
-    }
-
-    int vf_TypePool::cpool_get_array(unsigned short cp_idx, SmConstant *ref) {
-        assert(ref);
-        if( !cpool_is_reftype(cp_idx) ) return false;
-
-        unsigned short name_idx = class_get_cp_class_name_index(k_class, cp_idx);
-        if( name_idx >= k_cp_length ) return false;
-
-        const char* name = class_get_cp_utf8_bytes( k_class, name_idx );
-        int len = (int)strlen(name);
-
-
-        //validate dimensions
-        int ptr = 0;
-        while (name[ptr] == '[' ) {
-            ptr++;
-        }
-
-        //'name' does not contain final '[', so max dimension of class 'name' is 254
-        if( ptr > 254 ) return false;
-
-
-
-        char* arr_name = (char*)classwide->mem.malloc(len + 4);
-        arr_name[0] = '[';
-
-        if( name[0] == '[' ) {
-            tc_memcpy(arr_name + 1, name, len);
-            *ref = get_ref_type(arr_name, len + 1);
-        } else {
-            arr_name[1] = 'L';
-            tc_memcpy(arr_name + 2, name, len);
-            arr_name[len + 2] = ';';
-            *ref = get_ref_type(arr_name, len + 3);
-        }
-
-        classwide->mem.dealloc_last(arr_name, len + 4);
-        return true;
-    }
-
-
-    int vf_TypePool::cpool_get_field(unsigned short cp_idx, SmConstant *ref, SmConstant *value) {
-        //check it is a field
-        if( !cp_idx || cp_idx >= k_cp_length || class_get_cp_tag( k_class, cp_idx ) != _CONSTANT_Fieldref ) {
-            return false;
-        }
-
-        unsigned short class_idx = class_get_cp_ref_class_index( k_class, cp_idx );
-        if( !cpool_get_class(class_idx, ref) ) return false;
-
-        unsigned short name_and_type_idx = class_get_cp_ref_name_and_type_index( k_class, cp_idx );
-        if( !name_and_type_idx || name_and_type_idx >= k_cp_length || class_get_cp_tag( k_class, name_and_type_idx ) != _CONSTANT_NameAndType ) return false;
-
-        //TODO: do we need this check?
-        //unsigned short name_idx = class_get_cp_name_index( k_class, name_and_type_idx );
-        //if( !name_idx || name_idx >= k_cp_length || class_get_cp_tag( k_class, name_idx ) != _CONSTANT_Utf8 ) return false;
-
-        //get filed type
-        unsigned short type_idx = class_get_cp_descriptor_index( k_class, name_and_type_idx );
-        if( !type_idx || type_idx >= k_cp_length || class_get_cp_tag( k_class, type_idx ) != _CONSTANT_Utf8 ) return false;
-
-        const char *type = class_get_cp_utf8_bytes( k_class, type_idx );
-        *value = get_type(type);
-
-        return true;
-    }
-
-    int vf_TypePool::cpool_method_start(unsigned short cp_idx, const char **state, SmConstant *objectref, 
-        unsigned short *name_idx, int opcode) {
-
-            ClassConstantPoolTags expected_tag = opcode == OP_INVOKEINTERFACE ? _CONSTANT_InterfaceMethodref : _CONSTANT_Methodref;
-
-            //check it is a method
-            if( !cp_idx || cp_idx >= k_cp_length || class_get_cp_tag( k_class, cp_idx ) != expected_tag ) {
-                return false;
-            }
-
-            unsigned short class_idx = class_get_cp_ref_class_index( k_class, cp_idx );
-            if( opcode == OP_INVOKEVIRTUAL || opcode == OP_INVOKESPECIAL ) {
-                if( !cpool_get_class(class_idx, objectref) ) return false;
-            } else {
-                if( !cpool_get_class(class_idx, 0) ) return false;
-                (*objectref) = sm_get_const_object();
-            }
-
-            unsigned short name_and_type_idx = class_get_cp_ref_name_and_type_index( k_class, cp_idx );
-            if( !name_and_type_idx || name_and_type_idx >= k_cp_length || class_get_cp_tag( k_class, name_and_type_idx ) != _CONSTANT_NameAndType ) return false;
-
-            *name_idx = class_get_cp_name_index( k_class, name_and_type_idx );
-            //TODO: do we need this check?
-            if( !(*name_idx) || *name_idx >= k_cp_length || class_get_cp_tag( k_class, *name_idx ) != _CONSTANT_Utf8 ) return false;
-
-            //get filed type or function args & rettype
-            unsigned short type_idx = class_get_cp_descriptor_index( k_class, name_and_type_idx );
-            if( !type_idx || type_idx >= k_cp_length || class_get_cp_tag( k_class, type_idx ) != _CONSTANT_Utf8 ) return false;
-
-            (*state) = class_get_cp_utf8_bytes( k_class, type_idx );
-            return true;
-        }
-
-
-        //find return type and count number of arguments
-        int vf_TypePool::cpool_method_get_rettype(const char **state, SmConstant *rettype, int *args_sz) {
-            const char *name = (*state);
-            if( name[0] != '(' ) return 0;
-
-            int i = 1;
-            //count number of args: skip '['s and all between 'L' and ';'
-            (*args_sz) = 0;
-            bool on = true;
-            char current;
-            while ( (current = name[i]) != ')' ) {
-                if( !current ) return 0;
-                if( current == 'L' ) on = false;
-                if( current == ';' ) on = true;
-                if( on && current != '[') {
-                    (*args_sz)++;
-                    //it is long or double and not an array of long or double
-                    if ((current == 'J' || current == 'D') && name[i-1] != '[') {
-                        (*args_sz)++;
-                    }
-                }
-                i++;
-            }
-            (*state) = i == 1 ? 0 : name + 1;
-            name = name + i + 1;
-
-            *rettype = get_type(name);
-            return 1;
-        }
-
-        int vf_TypePool::cpool_method_next_arg(const char **state, SmConstant *argument) {
-            const char *name = (*state);
-
-            //define name length
-            int len = 0;
-            //skip '['s
-            if ((*state)[len] == '[') {
-                while( (*state)[++len] == '[' ) ;//len++;
-            }
-            //skip up to ';'
-            if( (*state)[len] == 'L' ) {
-                while( (*state)[++len] != ';' ) ;
-                // already checked for '\0' by cpool_method_getrettype
-                //        {
-                //            assert((*state)[len]);
-                //            if( !(*state)[len] ) return false;
-                //            len++;
-                //        }
-            }
-            len++;
-
-            *argument = get_type((*state), len);
-
-            (*state) = (*state)[len] == ')' ? 0 : (*state) + len;
-            return true;
-        }
-
-        int vf_TypePool::cpool_method_is_constructor_call(unsigned short name_idx) {
-            return !strcmp(class_get_cp_utf8_bytes( k_class, name_idx ), "<init>");
-        }
-
-} // namespace CPVerifier
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+#include <assert.h>
+#include "tpool.h"
+#include "context_base.h"
+
+namespace CPVerifier {
+
+    vf_TypePool::vf_TypePool(SharedClasswideData *_classwide, class_handler _klass, unsigned table_incr)
+        : classwide(_classwide), tableIncr(table_incr),
+        validTypesTableMax(0), validTypesTableSz(1), validTypes(0)
+    {
+        const_object = const_class = const_string = const_throwable = const_arrayref_of_bb =
+            const_arrayref_of_char = const_arrayref_of_double = const_arrayref_of_float =
+            const_arrayref_of_integer = const_arrayref_of_long = const_arrayref_of_short = 
+            const_arrayref_of_object = const_this = SM_NONE;
+
+        k_class = _klass;
+        k_cp_length = class_get_cp_size( k_class );
+    }
+
+    /*
+    * Returns name length if it is array of boolean or 0
+    */
+    inline int vf_TypePool::is_bool_array_conv_needed(const char *type_name, int length) {
+        return length > 1 && type_name[length - 1] == 'Z' && type_name[length - 2] == '[';
+    }
+
+    /*
+    * Get SmConstant by type name.
+    */
+    SmConstant vf_TypePool::get_ref_type(const char *type_name, int length) {
+        //TODO: this assert raise false alarms when type name starts with 'L'
+        //assert(type_name[0] != 'L');
+
+        // find type in hash
+        vf_HashEntry_t *entry = hash.NewHashEntry( type_name, length );
+        unsigned index = entry->data_index;
+        if( !index ) {
+            //convert array of booleans to array of bytes
+            if( is_bool_array_conv_needed(type_name, length) ) {
+                char *new_name = (char*)classwide->mem.malloc(length+1);
+                tc_memcpy(new_name, type_name, length);
+                new_name[length-1] = 'B';
+                index = get_ref_type(new_name, length).getReferenceIdx();
+                classwide->mem.dealloc_last(new_name, length+1);
+            }
+            // Get next free table entry index
+            if( !index ) {
+                index = check_table();
+                validTypes[index].cls = 0;
+                validTypes[index].name = entry->key;
+            }
+            entry->data_index = index;
+        }
+
+        assert(index < validTypesTableSz);
+        return SmConstant::getReference(index);
+    }
+
+    SmConstant vf_TypePool::get_primitive_type(const char type_char) {
+        switch( type_char ) {
+        case 'I':
+        case 'B':
+        case 'Z':
+        case 'C':
+        case 'S':
+            return SM_INTEGER;
+        case 'J':
+            return SM_LONG;
+        case 'F':
+            return SM_FLOAT;
+        case 'V':
+            return SM_BOGUS;
+        case 'D':
+            return SM_DOUBLE;
+        default:
+            assert(0);
+            return SM_BOGUS;
+        }
+    }
+
+    SmConstant vf_TypePool::get_type(const char *type_name, int name_len) {
+        if( name_len > 1 ) {
+            if( type_name[0] == '[' ) {
+                return get_ref_type(type_name, name_len);
+            }
+
+            if( type_name[0] == 'L' ) {
+                return get_ref_type(type_name + 1, name_len - 2);
+            }
+
+            return SM_BOGUS;
+        } else {
+            return get_primitive_type(type_name[0]);
+        }
+    }
+
+
+    SmConstant vf_TypePool::get_ref_from_array(SmConstant element) {
+        if( element == SM_NULL ) return SM_NULL;
+
+        assert(element.isReference());
+        assert(sm_get_refname(element)[0] == '[');
+        return get_type(sm_get_refname(element) + 1);
+    }
+
+
+    int vf_TypePool::mustbe_assignable(SmConstant from, SmConstant to) {
+        if( from == to || to == SM_NONE || to == SM_BOGUS ) return true;
+        if( from == SM_BOGUS ) return false;
+
+        if( to.isReference() ) {
+            if( from == SM_NULL ) return true;
+
+            if( from.isReference() ) {
+                return ref_mustbe_assignable(from, to);
+            }
+
+            return false;
+        }
+
+        if( !to.isPrimitive() ) {
+            assert( to != from ); // checked above
+            return false;
+        }
+
+        //migth have to change switch below if merging is done with constants
+        assert( from != SM_NONE );
+        assert( from != SM_ONEWORDED );
+        assert( from != SM_REF_OR_UNINIT_OR_RETADR );
+        assert( from != SM_REF_OR_UNINIT );
+        assert( from != SM_ANYARRAY );
+        assert( from != SM_BOGUS );
+
+        switch ( to.c ) {
+        case SM_ONEWORDED:
+            return !from.isLongOrDouble();
+
+        case SM_REF_OR_UNINIT_OR_RETADR:
+            return from == SM_NULL || from == SM_THISUNINIT || !from.isPrimitive();
+
+        case SM_REF_OR_UNINIT:
+            return from == SM_NULL || from == SM_THISUNINIT || from.isNewObject() || from.isReference();
+
+        case SM_ANYARRAY:
+            return from == SM_NULL || from.isReference() && sm_get_refname(from)[0] == '[';
+
+        case SM_NULL:
+        case SM_THISUNINIT:
+            assert(0);
+            return false;
+
+        case SM_HIGH_WORD:
+        case SM_INTEGER:
+        case SM_FLOAT:
+        case SM_LONG:
+        case SM_DOUBLE:
+        case SM_BOGUS:
+            return false;
+        default:
+            assert(0);
+            return false;
+        }
+    }
+
+    int vf_TypePool::ref_mustbe_assignable(SmConstant from, SmConstant to) {
+        if( to == sm_get_const_object() ) return true;
+
+        vf_ValidType *to_type = getVaildType(to.getReferenceIdx());
+        vf_ValidType *from_type = getVaildType(from.getReferenceIdx());
+
+        const char *to_name = to_type->name;
+        const char *from_name = from_type->name;
+
+        int to_array = to_name[0] == '[';
+        int from_array = from_name[0] == '[';
+
+        if( to_array && !from_array ) {
+            return false;
+        } else if( to_array && from_array ) {
+            int dim = 0;
+            while( to_name[dim] == '[' && from_name[dim] == '[' ) dim++;
+
+            if( from_name[dim] != 'L' && from_name[dim] != '[' ) {
+                //primitive type
+                dim--;
+            }
+
+            if( to_name[dim] != 'L' ) return false;
+
+            if( from_name[dim] == 'L' ) {
+                //merge refs
+                return ref_mustbe_assignable(get_type(from_name + dim), get_type(to_name + dim) );
+            } else {
+                //to must be Object or an interface
+                return ref_mustbe_assignable(sm_get_const_object(), get_type(to_name + dim) );
+            }
+        } else if( from_array ) {
+            //from is an array, to is not an array
+
+            //must be checked before
+            assert( from != to );
+
+            return to == sm_get_const_object() || !strcmp(to_name, "java/lang/Cloneable") || 
+                    !strcmp(to_name, "java/io/Serializable");
+        } else {
+            //both not arrays
+
+            //check whether TO class is loaded
+            if( !to_type->cls ) {
+                to_type->cls = vf_resolve_class(k_class, to_type->name, false);
+                if( !to_type->cls ) to_type->cls = CLASS_NOT_LOADED;
+            }
+
+            if( to_type->cls && to_type->cls != CLASS_NOT_LOADED ) {
+                //if to is loaded and it is an interface, treat it as an object
+                if( class_is_interface_( to_type->cls ) ) {
+                    return true;
+                }
+            } else {
+                NewConstraint(from_type->name, to_type->name);
+                return true;
+            }
+
+            //check whether FROM class is loaded
+            if( !from_type->cls ) {
+                from_type->cls = vf_resolve_class(k_class, from_type->name, false);
+                if( !from_type->cls ) from_type->cls = CLASS_NOT_LOADED;
+            }
+
+            if( from_type->cls && from_type->cls != CLASS_NOT_LOADED ) {
+                return vf_is_extending(from_type->cls, to_type->cls);
+            } else {
+                NewConstraint(from_type->name, to_type->name);
+                return 1;
+            }
+        }
+    }
+
+    //check if expected_ref is a super class of 'this', its package differs
+    int vf_TypePool::checkSuperAndPackage(SmConstant expected_ref) {
+        //check that expected ref is a super of 'this'
+        vf_ValidType *expected_type = getVaildType(expected_ref.getReferenceIdx());
+        class_handler &referred = expected_type->cls;
+
+        if( !referred ) {
+            //try to get class
+            referred = vf_resolve_class(k_class, expected_type->name, false);
+
+            if( !referred ) {
+                referred = CLASS_NOT_LOADED;
+            }
+        }
+
+        if( referred == CLASS_NOT_LOADED ) {
+            //referred class can't be resolved ==> it's not a super class
+//#ifndef NDEBUG
+//            class_handler k = k_class;
+//            while(k) {
+//                assert(strcmp(class_get_name(k), expected_type->name));
+//                k = class_get_super_class(k);
+//            }
+//#endif
+            return false;
+        }
+
+        return !class_is_same_package(k_class, referred) && vf_is_extending(k_class, referred);
+    }
+
+    //check if expected_ref is a super class of 'this', its package differs, and it's protected
+    int vf_TypePool::checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx) {
+        //check if expected_ref is a super class of 'this', its package differs
+        if( !checkSuperAndPackage(expected_ref) ) {
+            return _FALSE;
+        }
+
+        //check further
+        //check that they are in different packages and method is protected
+        method_handler method = class_resolve_method(k_class, method_idx);
+
+        if (!method || method_is_static(method)) {
+            //it's not a VerifyError
+            return _FALSE;
+        }
+        
+        // for arrays function clone is public
+        return !method_is_protected(method) ? _FALSE : !memcmp(method_get_name(method), "clone", 6) ? _CLONE : _TRUE;
+    }
+
+    //check if expected_ref is a super class of 'this', its package differs, and it's protected
+    int vf_TypePool::checkFieldAccess(SmConstant expected_ref, unsigned short field_idx) {
+        //check if expected_ref is a super class of 'this', its package differs
+        if( !checkSuperAndPackage(expected_ref) ) {
+            return _FALSE;
+        }
+
+        //check further
+        //check that they are in different packages and method is protected
+        field_handler field = class_resolve_nonstatic_field(k_class, field_idx);
+
+        if (!field) {
+            //it's not a VerifyError
+            return _FALSE;
+        }
+        
+        // for arrays function clone is public
+        return field_is_protected(field) ? _TRUE : _FALSE;
+    }
+
+
+    void vf_TypePool::NewConstraint(const char *available,
+        const char *required)
+    {
+        vf_TypeConstraint *constraint;
+
+        // lookup constraint
+        for( constraint = classwide->class_constraints; constraint; constraint = constraint->next) {
+            if( constraint->target == required && constraint->source == available ) {
+                // this constraint is already present
+                return;
+            }
+        }
+
+        // set constraint
+        constraint = (vf_TypeConstraint*)classwide->constraintPool.malloc(sizeof(vf_TypeConstraint));
+        constraint->target = required;
+        constraint->source = available;
+        constraint->next = classwide->class_constraints;
+        classwide->class_constraints = constraint;
+
+        return;
+    }
+
+    SmConstant vf_TypePool::cpool_get_ldcarg(unsigned short cp_idx) {
+        if( cp_idx >= k_cp_length || !cp_idx ) return SM_BOGUS;
+
+        switch (class_get_cp_tag( k_class, cp_idx ) ) {
+        case _CONSTANT_String: 
+            return sm_get_const_string();
+
+        case _CONSTANT_Integer: 
+            return SM_INTEGER;
+
+        case _CONSTANT_Float:
+            return SM_FLOAT;
+
+        case _CONSTANT_Class:
+            //check if it's a 1.5 class (major version is 49)
+            return classwide->k_major < 49 ? SM_BOGUS : sm_get_const_class();
+
+        default:
+            return SM_BOGUS;
+        }
+    }
+
+
+    SmConstant vf_TypePool::cpool_get_ldc2arg(unsigned short cp_idx) {
+        if( cp_idx >= k_cp_length || !cp_idx ) return SM_BOGUS;
+
+        switch (class_get_cp_tag( k_class, cp_idx ) ) {
+        case _CONSTANT_Double: 
+            return SM_DOUBLE;
+
+        case _CONSTANT_Long: 
+            return SM_LONG;
+
+        default:
+            return SM_BOGUS;
+        }
+    }
+
+
+    int vf_TypePool::cpool_is_reftype(unsigned short cp_idx) {
+        return cp_idx && cp_idx < k_cp_length && class_get_cp_tag( k_class, cp_idx ) == _CONSTANT_Class;
+    }
+
+
+    int vf_TypePool::cpool_get_class(unsigned short cp_idx, SmConstant *ref, int expected_dim) {
+        if( !cpool_is_reftype(cp_idx) ) return false;
+
+        unsigned short name_idx = class_get_cp_class_name_index(k_class, cp_idx);
+        if( name_idx >= k_cp_length ) return false;
+
+        const char* name = class_get_cp_utf8_bytes( k_class, name_idx );
+
+        //validate dimensions
+        int ptr = 0;
+        while (name[ptr] == '[' ) {
+            ptr++;
+        }
+        //'name' already contains final '[', so max dimension of class 'name' is 255
+        if( ptr <  expected_dim || ptr > 255 ) return false;
+
+        //array is not allowed here
+        if( ptr && expected_dim == -1 ) return false;
+
+
+        //TODO: do we need to resolve if we don't need SmConstant?
+        //e.g. do we need to resolve class of a static variable?
+        //constantpool validation should be done whereever else
+        if( ref ) *ref = get_ref_type(name, (int)strlen(name));
+
+        return true;
+    }
+
+    int vf_TypePool::cpool_get_array(unsigned short cp_idx, SmConstant *ref) {
+        assert(ref);
+        if( !cpool_is_reftype(cp_idx) ) return false;
+
+        unsigned short name_idx = class_get_cp_class_name_index(k_class, cp_idx);
+        if( name_idx >= k_cp_length ) return false;
+
+        const char* name = class_get_cp_utf8_bytes( k_class, name_idx );
+        int len = (int)strlen(name);
+
+
+        //validate dimensions
+        int ptr = 0;
+        while (name[ptr] == '[' ) {
+            ptr++;
+        }
+
+        //'name' does not contain final '[', so max dimension of class 'name' is 254
+        if( ptr > 254 ) return false;
+
+
+
+        char* arr_name = (char*)classwide->mem.malloc(len + 4);
+        arr_name[0] = '[';
+
+        if( name[0] == '[' ) {
+            tc_memcpy(arr_name + 1, name, len);
+            *ref = get_ref_type(arr_name, len + 1);
+        } else {
+            arr_name[1] = 'L';
+            tc_memcpy(arr_name + 2, name, len);
+            arr_name[len + 2] = ';';
+            *ref = get_ref_type(arr_name, len + 3);
+        }
+
+        classwide->mem.dealloc_last(arr_name, len + 4);
+        return true;
+    }
+
+
+    int vf_TypePool::cpool_get_field(unsigned short cp_idx, SmConstant *ref, SmConstant *value) {
+        //check it is a field
+        if( !cp_idx || cp_idx >= k_cp_length || class_get_cp_tag( k_class, cp_idx ) != _CONSTANT_Fieldref ) {
+            return false;
+        }
+
+        unsigned short class_idx = class_get_cp_ref_class_index( k_class, cp_idx );
+        if( !cpool_get_class(class_idx, ref) ) return false;
+
+        unsigned short name_and_type_idx = class_get_cp_ref_name_and_type_index( k_class, cp_idx );
+        if( !name_and_type_idx || name_and_type_idx >= k_cp_length || class_get_cp_tag( k_class, name_and_type_idx ) != _CONSTANT_NameAndType ) return false;
+
+        //TODO: do we need this check?
+        //unsigned short name_idx = class_get_cp_name_index( k_class, name_and_type_idx );
+        //if( !name_idx || name_idx >= k_cp_length || class_get_cp_tag( k_class, name_idx ) != _CONSTANT_Utf8 ) return false;
+
+        //get filed type
+        unsigned short type_idx = class_get_cp_descriptor_index( k_class, name_and_type_idx );
+        if( !type_idx || type_idx >= k_cp_length || class_get_cp_tag( k_class, type_idx ) != _CONSTANT_Utf8 ) return false;
+
+        const char *type = class_get_cp_utf8_bytes( k_class, type_idx );
+        *value = get_type(type);
+
+        return true;
+    }
+
+    int vf_TypePool::cpool_method_start(unsigned short cp_idx, const char **state, SmConstant *objectref, 
+        unsigned short *name_idx, int opcode) {
+
+            ClassConstantPoolTags expected_tag = opcode == OP_INVOKEINTERFACE ? _CONSTANT_InterfaceMethodref : _CONSTANT_Methodref;
+
+            //check it is a method
+            if( !cp_idx || cp_idx >= k_cp_length || class_get_cp_tag( k_class, cp_idx ) != expected_tag ) {
+                return false;
+            }
+
+            unsigned short class_idx = class_get_cp_ref_class_index( k_class, cp_idx );
+            if( opcode == OP_INVOKEVIRTUAL || opcode == OP_INVOKESPECIAL ) {
+                if( !cpool_get_class(class_idx, objectref) ) return false;
+            } else {
+                if( !cpool_get_class(class_idx, 0) ) return false;
+                (*objectref) = sm_get_const_object();
+            }
+
+            unsigned short name_and_type_idx = class_get_cp_ref_name_and_type_index( k_class, cp_idx );
+            if( !name_and_type_idx || name_and_type_idx >= k_cp_length || class_get_cp_tag( k_class, name_and_type_idx ) != _CONSTANT_NameAndType ) return false;
+
+            *name_idx = class_get_cp_name_index( k_class, name_and_type_idx );
+            //TODO: do we need this check?
+            if( !(*name_idx) || *name_idx >= k_cp_length || class_get_cp_tag( k_class, *name_idx ) != _CONSTANT_Utf8 ) return false;
+
+            //get filed type or function args & rettype
+            unsigned short type_idx = class_get_cp_descriptor_index( k_class, name_and_type_idx );
+            if( !type_idx || type_idx >= k_cp_length || class_get_cp_tag( k_class, type_idx ) != _CONSTANT_Utf8 ) return false;
+
+            (*state) = class_get_cp_utf8_bytes( k_class, type_idx );
+            return true;
+        }
+
+
+        //find return type and count number of arguments
+        int vf_TypePool::cpool_method_get_rettype(const char **state, SmConstant *rettype, int *args_sz) {
+            const char *name = (*state);
+            if( name[0] != '(' ) return 0;
+
+            int i = 1;
+            //count number of args: skip '['s and all between 'L' and ';'
+            (*args_sz) = 0;
+            bool on = true;
+            char current;
+            while ( (current = name[i]) != ')' ) {
+                if( !current ) return 0;
+                if( current == 'L' ) on = false;
+                if( current == ';' ) on = true;
+                if( on && current != '[') {
+                    (*args_sz)++;
+                    //it is long or double and not an array of long or double
+                    if ((current == 'J' || current == 'D') && name[i-1] != '[') {
+                        (*args_sz)++;
+                    }
+                }
+                i++;
+            }
+            (*state) = i == 1 ? 0 : name + 1;
+            name = name + i + 1;
+
+            *rettype = get_type(name);
+            return 1;
+        }
+
+        int vf_TypePool::cpool_method_next_arg(const char **state, SmConstant *argument) {
+            const char *name = (*state);
+
+            //define name length
+            int len = 0;
+            //skip '['s
+            if ((*state)[len] == '[') {
+                while( (*state)[++len] == '[' ) ;//len++;
+            }
+            //skip up to ';'
+            if( (*state)[len] == 'L' ) {
+                while( (*state)[++len] != ';' ) ;
+                // already checked for '\0' by cpool_method_getrettype
+                //        {
+                //            assert((*state)[len]);
+                //            if( !(*state)[len] ) return false;
+                //            len++;
+                //        }
+            }
+            len++;
+
+            *argument = get_type((*state), len);
+
+            (*state) = (*state)[len] == ')' ? 0 : (*state) + len;
+            return true;
+        }
+
+        int vf_TypePool::cpool_method_is_constructor_call(unsigned short name_idx) {
+            return !strcmp(class_get_cp_utf8_bytes( k_class, name_idx ), "<init>");
+        }
+
+} // namespace CPVerifier

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.cpp
            ('svn:executable' removed)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h Fri Oct 12 07:42:03 2007
@@ -1,285 +1,285 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-#ifndef __TPOOL_H_
-#define __TPOOL_H_
-
-
-#include "verifier.h"
-#include "stackmap.h"
-#include "memory.h"
-#include "ver_utils.h"
-
-namespace CPVerifier {
-
-    /**
-    * Verification type constraint structure.
-    */
-    struct vf_TypeConstraint {
-        const char *source;         // constraint source class name
-        const char *target;         // constraint target class name
-        vf_TypeConstraint *next;  // next constraint
-    };
-    typedef vf_TypeConstraint* vf_TypeConstraint_p;
-
-    //verifier's data stored in classloader
-    typedef struct {
-        Memory    *pool;        // constraint memory pool
-        vf_Hash *hash;        // constraint hash table
-        vf_Hash *string;      // string pool hash table
-    } vf_ClassLoaderData_t;
-
-
-    struct vf_ValidType {
-        class_handler cls;      //class handler
-        const char*   name;     //name of the class
-    };
-
-#define CLASS_NOT_LOADED ((class_handler)-1)
-
-    class SharedClasswideData;
-
-    /**
-    * utility class for dealing with Java types, converting object references to SmConstant,
-    * parsing constantpool, etc
-    * TODO: remove constant pool parse and verification from the bytecode verifier
-    */
-    class vf_TypePool {
-
-    public:
-        vf_TypePool(SharedClasswideData *_classwide, class_handler _klass, unsigned table_incr);
-
-        ~vf_TypePool() {
-            if( validTypes ) tc_free(validTypes);
-        }
-
-        SmConstant cpool_get_ldcarg(unsigned short cp_idx);
-        SmConstant cpool_get_ldc2arg(unsigned short cp_idx);
-        int cpool_is_reftype(unsigned short cp_idx);
-        int cpool_get_class(unsigned short cp_idx, SmConstant *ref, int expected_dim = 0);
-
-        int cpool_get_array(unsigned short cp_idx, SmConstant *ref);
-        int cpool_get_field(unsigned short cp_idx, SmConstant *ref, SmConstant *value);
-        int cpool_method_start(unsigned short cp_idx, const char **state, SmConstant *objectref,
-            unsigned short *name_idx, int opcode);
-        int cpool_method_get_rettype(const char **state, SmConstant *rettype, int *args_sz);
-        int cpool_method_next_arg(const char **state, SmConstant *argument);
-        int cpool_method_is_constructor_call(unsigned short name_idx);
-
-
-        SmConstant get_type(const char *type_name, int name_len);
-        SmConstant get_ref_type(const char *type_name, int name_len);
-        SmConstant get_primitive_type(const char type_char);
-        SmConstant get_ref_from_array(SmConstant element);
-
-
-        SmConstant get_type(const char *type_name) {
-            return get_type(type_name, (int)strlen(type_name) );
-        }
-
-        int mustbe_assignable(SmConstant from, SmConstant to);
-        int ref_mustbe_assignable(SmConstant from, SmConstant to);
-
-
-        vf_ValidType *getVaildType(unsigned index) {
-            assert(index && validTypes && index < validTypesTableSz);
-            return validTypes + index;
-        }
-
-        class_handler sm_get_handler(SmConstant type) {
-            unsigned index = type.getReferenceIdx();
-            return getVaildType(index)->cls;
-        }
-
-        const char* sm_get_refname(SmConstant type) {
-            unsigned index = type.getReferenceIdx();
-            return getVaildType(index)->name;
-        }
-
-        //return SmConstant (known verification type) corresponding to 'type_name' and cache result in the 'cache'
-        SmConstant sm_get_const_existing(const char* type_name, SmConstant* cache) {
-            if( (*cache) == SM_NONE ) {
-                //TODO: check asm code for strlen
-                (*cache) = get_ref_type(type_name, (int)strlen(type_name));
-            }
-            return (*cache);
-        }
-
-        //return SmConstant (known verification type) corresponding to the super class of the class being verified
-        //returned value is cached
-        SmConstant sm_get_const_super() {
-            const char* _super = class_get_name( class_get_super_class( k_class ));
-            return get_ref_type(_super, (int)strlen(_super) );
-        }
-
-        //return SmConstant (known verification type) corresponding to the class being verified
-        //returned value is cached
-        SmConstant sm_get_const_this() {
-            return sm_get_const_existing(class_get_name(k_class), &const_this);
-        }
-
-        //return SmConstant (known verification type) corresponding to java/lang/Object
-        //returned value is cached
-        SmConstant sm_get_const_object() {
-            return sm_get_const_existing("java/lang/Object", &const_object);
-        }
-
-        //return SmConstant (known verification type) corresponding to java/lang/Class
-        //returned value is cached
-        SmConstant sm_get_const_class() {
-            return sm_get_const_existing("java/lang/Class", &const_class);
-        }
-
-        //return SmConstant (known verification type) corresponding to java/lang/String
-        //returned value is cached
-        SmConstant sm_get_const_string() {
-            return sm_get_const_existing("java/lang/String", &const_string);
-        }
-
-        //return SmConstant (known verification type) corresponding to java/lang/Throwable
-        //returned value is cached
-        SmConstant sm_get_const_throwable() {
-            return sm_get_const_existing("java/lang/Throwable", &const_throwable);
-        }
-
-        //return SmConstant (known verification type) corresponding to uint8[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_bb() {
-            return sm_get_const_existing("[B", &const_arrayref_of_bb);
-        }
-
-        //return SmConstant (known verification type) corresponding to char[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_char() {
-            return sm_get_const_existing("[C", &const_arrayref_of_char);
-        }
-
-        //return SmConstant (known verification type) corresponding to double[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_double() {
-            return sm_get_const_existing("[D", &const_arrayref_of_double);
-        }
-
-        //return SmConstant (known verification type) corresponding to float[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_float() {
-            return sm_get_const_existing("[F", &const_arrayref_of_float);
-        }
-
-        //return SmConstant (known verification type) corresponding to int[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_integer() {
-            return sm_get_const_existing("[I", &const_arrayref_of_integer);
-        }
-
-        //return SmConstant (known verification type) corresponding to long[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_long() {
-            return sm_get_const_existing("[J", &const_arrayref_of_long);
-        }
-
-        //return SmConstant (known verification type) corresponding to short[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_short() {
-            return sm_get_const_existing("[S", &const_arrayref_of_short);
-        }
-
-        //return SmConstant (known verification type) corresponding to Object[]
-        //returned value is cached
-        SmConstant sm_get_const_arrayref_of_object() {
-            return sm_get_const_existing("[Ljava/lang/Object;", &const_arrayref_of_object);
-        }
-
-        //return SmConstant represented array of specified type
-        //the type is specified in the OP_NEWARRAY instruction. See the spec for possible types
-        SmConstant sm_get_const_arrayref(uint8 see_spec) {
-            switch ( see_spec ) {
-        case 4: //T_BOOLEAN
-        case 8: //T_BYTE
-            return sm_get_const_arrayref_of_bb();
-        case 5: //T_CHAR
-            return sm_get_const_arrayref_of_char();
-        case 6: //T_FLOAT
-            return sm_get_const_arrayref_of_float();
-        case 7: //T_DOUBLE
-            return sm_get_const_arrayref_of_double();
-        case 9: //T_SHORT
-            return sm_get_const_arrayref_of_short();
-        case 10: //T_INT
-            return sm_get_const_arrayref_of_integer();
-        case 11: //T_LONG
-            return sm_get_const_arrayref_of_long();
-            }
-            assert(0);
-            return SM_BOGUS;
-        }
-
-        //check if expected_ref is a super class of 'this', its package differs, and it's protected
-        enum FieldAndMethodCheck {_FALSE, _CLONE, _TRUE};
-        int checkFieldAccess(SmConstant expected_ref, unsigned short method_idx);
-        int checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx);
-        int checkSuperAndPackage(SmConstant expected_ref);
-    private:
-        //ref to the main class of the verifier
-        SharedClasswideData *classwide;
-
-        //class handler of the class being verified
-        class_handler k_class;
-
-        //constantpool length
-        unsigned k_cp_length;
-
-        //hash table storing class names
-        vf_Hash hash;
-        vf_ValidType *validTypes;
-        unsigned tableIncr;
-        unsigned validTypesTableMax;
-        unsigned validTypesTableSz;
-
-        /*****************/
-        //cache for SmConstant constants;
-        SmConstant const_object, const_class, const_string, const_throwable, const_arrayref_of_bb, 
-            const_arrayref_of_char, const_arrayref_of_double, const_arrayref_of_float, 
-            const_arrayref_of_integer, const_arrayref_of_long, const_arrayref_of_short,
-            const_arrayref_of_object, const_this;
-
-
-        void NewConstraint(const char *available, const char *required);
-
-        //Get next free table entry index.
-        //Reallocate table if out of free entries.
-        unsigned check_table() {
-            if( validTypesTableSz + 1 >= validTypesTableMax ) {
-                validTypesTableMax += tableIncr;
-                validTypes = (vf_ValidType*)tc_realloc(validTypes, sizeof(vf_ValidType) * validTypesTableMax);
-            }
-            return validTypesTableSz++;
-        }
-
-        int is_bool_array_conv_needed(const char *type_name, int length);
-
-    };
-
-    class_handler vf_resolve_class( class_handler k_class, const char *name, bool need_load);
-    int vf_is_extending(class_handler from, class_handler to);
-
-} // namespace CPVerifier
-
-#endif
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+#ifndef __TPOOL_H_
+#define __TPOOL_H_
+
+
+#include "verifier.h"
+#include "stackmap.h"
+#include "memory.h"
+#include "ver_utils.h"
+
+namespace CPVerifier {
+
+    /**
+    * Verification type constraint structure.
+    */
+    struct vf_TypeConstraint {
+        const char *source;         // constraint source class name
+        const char *target;         // constraint target class name
+        vf_TypeConstraint *next;  // next constraint
+    };
+    typedef vf_TypeConstraint* vf_TypeConstraint_p;
+
+    //verifier's data stored in classloader
+    typedef struct {
+        Memory    *pool;        // constraint memory pool
+        vf_Hash *hash;        // constraint hash table
+        vf_Hash *string;      // string pool hash table
+    } vf_ClassLoaderData_t;
+
+
+    struct vf_ValidType {
+        class_handler cls;      //class handler
+        const char*   name;     //name of the class
+    };
+
+#define CLASS_NOT_LOADED ((class_handler)-1)
+
+    class SharedClasswideData;
+
+    /**
+    * utility class for dealing with Java types, converting object references to SmConstant,
+    * parsing constantpool, etc
+    * TODO: remove constant pool parse and verification from the bytecode verifier
+    */
+    class vf_TypePool {
+
+    public:
+        vf_TypePool(SharedClasswideData *_classwide, class_handler _klass, unsigned table_incr);
+
+        ~vf_TypePool() {
+            if( validTypes ) tc_free(validTypes);
+        }
+
+        SmConstant cpool_get_ldcarg(unsigned short cp_idx);
+        SmConstant cpool_get_ldc2arg(unsigned short cp_idx);
+        int cpool_is_reftype(unsigned short cp_idx);
+        int cpool_get_class(unsigned short cp_idx, SmConstant *ref, int expected_dim = 0);
+
+        int cpool_get_array(unsigned short cp_idx, SmConstant *ref);
+        int cpool_get_field(unsigned short cp_idx, SmConstant *ref, SmConstant *value);
+        int cpool_method_start(unsigned short cp_idx, const char **state, SmConstant *objectref,
+            unsigned short *name_idx, int opcode);
+        int cpool_method_get_rettype(const char **state, SmConstant *rettype, int *args_sz);
+        int cpool_method_next_arg(const char **state, SmConstant *argument);
+        int cpool_method_is_constructor_call(unsigned short name_idx);
+
+
+        SmConstant get_type(const char *type_name, int name_len);
+        SmConstant get_ref_type(const char *type_name, int name_len);
+        SmConstant get_primitive_type(const char type_char);
+        SmConstant get_ref_from_array(SmConstant element);
+
+
+        SmConstant get_type(const char *type_name) {
+            return get_type(type_name, (int)strlen(type_name) );
+        }
+
+        int mustbe_assignable(SmConstant from, SmConstant to);
+        int ref_mustbe_assignable(SmConstant from, SmConstant to);
+
+
+        vf_ValidType *getVaildType(unsigned index) {
+            assert(index && validTypes && index < validTypesTableSz);
+            return validTypes + index;
+        }
+
+        class_handler sm_get_handler(SmConstant type) {
+            unsigned index = type.getReferenceIdx();
+            return getVaildType(index)->cls;
+        }
+
+        const char* sm_get_refname(SmConstant type) {
+            unsigned index = type.getReferenceIdx();
+            return getVaildType(index)->name;
+        }
+
+        //return SmConstant (known verification type) corresponding to 'type_name' and cache result in the 'cache'
+        SmConstant sm_get_const_existing(const char* type_name, SmConstant* cache) {
+            if( (*cache) == SM_NONE ) {
+                //TODO: check asm code for strlen
+                (*cache) = get_ref_type(type_name, (int)strlen(type_name));
+            }
+            return (*cache);
+        }
+
+        //return SmConstant (known verification type) corresponding to the super class of the class being verified
+        //returned value is cached
+        SmConstant sm_get_const_super() {
+            const char* _super = class_get_name( class_get_super_class( k_class ));
+            return get_ref_type(_super, (int)strlen(_super) );
+        }
+
+        //return SmConstant (known verification type) corresponding to the class being verified
+        //returned value is cached
+        SmConstant sm_get_const_this() {
+            return sm_get_const_existing(class_get_name(k_class), &const_this);
+        }
+
+        //return SmConstant (known verification type) corresponding to java/lang/Object
+        //returned value is cached
+        SmConstant sm_get_const_object() {
+            return sm_get_const_existing("java/lang/Object", &const_object);
+        }
+
+        //return SmConstant (known verification type) corresponding to java/lang/Class
+        //returned value is cached
+        SmConstant sm_get_const_class() {
+            return sm_get_const_existing("java/lang/Class", &const_class);
+        }
+
+        //return SmConstant (known verification type) corresponding to java/lang/String
+        //returned value is cached
+        SmConstant sm_get_const_string() {
+            return sm_get_const_existing("java/lang/String", &const_string);
+        }
+
+        //return SmConstant (known verification type) corresponding to java/lang/Throwable
+        //returned value is cached
+        SmConstant sm_get_const_throwable() {
+            return sm_get_const_existing("java/lang/Throwable", &const_throwable);
+        }
+
+        //return SmConstant (known verification type) corresponding to uint8[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_bb() {
+            return sm_get_const_existing("[B", &const_arrayref_of_bb);
+        }
+
+        //return SmConstant (known verification type) corresponding to char[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_char() {
+            return sm_get_const_existing("[C", &const_arrayref_of_char);
+        }
+
+        //return SmConstant (known verification type) corresponding to double[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_double() {
+            return sm_get_const_existing("[D", &const_arrayref_of_double);
+        }
+
+        //return SmConstant (known verification type) corresponding to float[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_float() {
+            return sm_get_const_existing("[F", &const_arrayref_of_float);
+        }
+
+        //return SmConstant (known verification type) corresponding to int[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_integer() {
+            return sm_get_const_existing("[I", &const_arrayref_of_integer);
+        }
+
+        //return SmConstant (known verification type) corresponding to long[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_long() {
+            return sm_get_const_existing("[J", &const_arrayref_of_long);
+        }
+
+        //return SmConstant (known verification type) corresponding to short[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_short() {
+            return sm_get_const_existing("[S", &const_arrayref_of_short);
+        }
+
+        //return SmConstant (known verification type) corresponding to Object[]
+        //returned value is cached
+        SmConstant sm_get_const_arrayref_of_object() {
+            return sm_get_const_existing("[Ljava/lang/Object;", &const_arrayref_of_object);
+        }
+
+        //return SmConstant represented array of specified type
+        //the type is specified in the OP_NEWARRAY instruction. See the spec for possible types
+        SmConstant sm_get_const_arrayref(uint8 see_spec) {
+            switch ( see_spec ) {
+        case 4: //T_BOOLEAN
+        case 8: //T_BYTE
+            return sm_get_const_arrayref_of_bb();
+        case 5: //T_CHAR
+            return sm_get_const_arrayref_of_char();
+        case 6: //T_FLOAT
+            return sm_get_const_arrayref_of_float();
+        case 7: //T_DOUBLE
+            return sm_get_const_arrayref_of_double();
+        case 9: //T_SHORT
+            return sm_get_const_arrayref_of_short();
+        case 10: //T_INT
+            return sm_get_const_arrayref_of_integer();
+        case 11: //T_LONG
+            return sm_get_const_arrayref_of_long();
+            }
+            assert(0);
+            return SM_BOGUS;
+        }
+
+        //check if expected_ref is a super class of 'this', its package differs, and it's protected
+        enum FieldAndMethodCheck {_FALSE, _CLONE, _TRUE};
+        int checkFieldAccess(SmConstant expected_ref, unsigned short method_idx);
+        int checkVirtualAccess(SmConstant expected_ref, unsigned short method_idx);
+        int checkSuperAndPackage(SmConstant expected_ref);
+    private:
+        //ref to the main class of the verifier
+        SharedClasswideData *classwide;
+
+        //class handler of the class being verified
+        class_handler k_class;
+
+        //constantpool length
+        unsigned k_cp_length;
+
+        //hash table storing class names
+        vf_Hash hash;
+        vf_ValidType *validTypes;
+        unsigned tableIncr;
+        unsigned validTypesTableMax;
+        unsigned validTypesTableSz;
+
+        /*****************/
+        //cache for SmConstant constants;
+        SmConstant const_object, const_class, const_string, const_throwable, const_arrayref_of_bb, 
+            const_arrayref_of_char, const_arrayref_of_double, const_arrayref_of_float, 
+            const_arrayref_of_integer, const_arrayref_of_long, const_arrayref_of_short,
+            const_arrayref_of_object, const_this;
+
+
+        void NewConstraint(const char *available, const char *required);
+
+        //Get next free table entry index.
+        //Reallocate table if out of free entries.
+        unsigned check_table() {
+            if( validTypesTableSz + 1 >= validTypesTableMax ) {
+                validTypesTableMax += tableIncr;
+                validTypes = (vf_ValidType*)tc_realloc(validTypes, sizeof(vf_ValidType) * validTypesTableMax);
+            }
+            return validTypesTableSz++;
+        }
+
+        int is_bool_array_conv_needed(const char *type_name, int length);
+
+    };
+
+    class_handler vf_resolve_class( class_handler k_class, const char *name, bool need_load);
+    int vf_is_extending(class_handler from, class_handler to);
+
+} // namespace CPVerifier
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/tpool.h
            ('svn:executable' removed)

Modified: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp?rev=584170&r1=584169&r2=584170&view=diff
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp (original)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp Fri Oct 12 07:42:03 2007
@@ -1,212 +1,212 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You 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.
- */
-/** 
- * @author Mikhail Loenko, Vladimir Molotkov
- */  
-
-
-
-#include <iostream>
-
-using namespace std;
-
-#include "verifier.h"
-#include "../java5/context_5.h"
-#include "../java6/context_6.h"
-#include "time.h"
-
-using namespace CPVerifier;
-using namespace CPVerifier_5;
-using namespace CPVerifier_6;
-
-static char err_message[5000];
-
-
-/**
-* Function provides initial java-5 verification of class.
-*
-* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
-* and either A or B is not loaded at the moment then a constraint 
-* "class A must be assignable to class B" is recorded into the classloader's data
-*/
-vf_Result
-vf_verify5_class( class_handler klass, unsigned verifyAll, char **error )
-{
-    int index;
-    vf_Result result = VF_OK;
-
-    // Create context
-    SharedClasswideData classwide(klass);
-    vf_Context_5 context(classwide);
-
-    // Verify method
-    for( index = 0; index < class_get_method_number( klass ); index++ ) {
-        result = context.verify_method(class_get_method( klass, index ));
-
-        if (result != VF_OK) {
-            *error = &(err_message[0]);
-            method_handler method = class_get_method( klass, index );
-            sprintf(*error, "%s/%s%s, pass: %d, instr: %d, reason: %s", class_get_name( klass ), method_get_name( method ), 
-                method_get_descriptor( method ), context.pass, context.processed_instruction, context.error_message );
-            break;
-        }
-    }
-
-    /**
-    * Set method constraints
-    */
-    context.set_class_constraints();
-
-    return result;
-} // vf_verify5_class
-
-
-/**
-* Function provides initial java-6 verification of class.
-*
-* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
-* and either A or B is not loaded at the moment then a constraint 
-* "class A must be assignable to class B" is recorded into the classloader's data
-*/
-vf_Result
-vf_verify6_class( class_handler klass, unsigned verifyAll, char **error )
-{
-    int index;
-    vf_Result result = VF_OK;
-
-    // Create contexts
-    SharedClasswideData classwide(klass);
-    vf_Context_5 context5(classwide);
-    vf_Context_6 context6(classwide);
-
-    bool skip_java6_verification_attempt = false;
-
-    // Verify method
-    for( index = 0; index < class_get_method_number( klass ); index++ ) {
-        method_handler method = class_get_method( klass, index );
-
-        //try Java6 verifying (using StackMapTable attribute)
-        if( !skip_java6_verification_attempt || method_get_stackmaptable(method) ) {
-            result = context6.verify_method(method);
-
-            if (result != VF_OK) {
-                //skip Java6 attempts for further methods unless they have StackMapTable
-                skip_java6_verification_attempt = true;
-                if (result == VF_ErrorStackmap) {
-                    //corrupted StackMapTable ==> throw an Error?
-                    *error = &(err_message[0]);
-                    sprintf(*error, "%s/%s%s, reason: %s", class_get_name( klass ), method_get_name( method ), 
-                        method_get_descriptor( method ), context6.error_message );
-                    return result;
-                }
-            }
-        }
-
-        if( result != VF_OK ) {
-            //try Java5 verifying
-            result = context5.verify_method(method);
-            if (result != VF_OK) {
-                //can't verify
-                *error = &(err_message[0]);
-                sprintf(*error, "%s/%s%s, pass: %d, instr: %d, reason: %s", class_get_name( klass ), method_get_name( method ), 
-                    method_get_descriptor( method ), context5.pass, context5.processed_instruction, context5.error_message );
-                return result;
-            }
-        }
-    }
-
-    /**
-    * Set method constraints
-    */
-    context5.set_class_constraints();
-
-    return result;
-} // vf_verify6_class
-
-
-/**
-* Function provides initial verification of class.
-*
-* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
-* and either A or B is not loaded at the moment then a constraint 
-* "class A must be assignable to class B" is recorded into the classloader's data
-*/
-vf_Result
-vf_verify_class( class_handler klass, unsigned verifyAll, char **error ) {
-    return class_get_version(klass) >= 50 ? vf_verify6_class(klass, verifyAll, error) : vf_verify5_class(klass, verifyAll, error);
-}
-
-/**
-* Function verifies all the constraints "class A must be assignable to class B"
-* that are recorded into the classloader for the given class
-* If some class is not loaded yet -- load it now
-*/
-vf_Result
-vf_verify_class_constraints( class_handler klass, unsigned verifyAll, char **error )
-{
-
-    // get class loader of current class
-    classloader_handler class_loader = class_get_class_loader( klass );
-
-    // get class loader verify data
-    vf_ClassLoaderData_t *cl_data =
-        (vf_ClassLoaderData_t*)cl_get_verify_data_ptr( class_loader );
-
-    // check class loader data
-    if( cl_data == NULL ) {
-        // no constraint data
-        return VF_OK;
-    }
-
-    // get class hash and memory pool
-    vf_Hash *hash = cl_data->hash;
-
-    // get constraints for class
-    vf_HashEntry_t *hash_entry = hash->Lookup( class_get_name( klass ) );
-    if( !hash_entry || !hash_entry->data_ptr ) {
-        // no constraint data
-        return VF_OK;
-    }
-
-    // check method constraints
-    vf_TypeConstraint *constraint = (vf_TypeConstraint*)hash_entry->data_ptr;
-    for( ; constraint; constraint = constraint->next )
-    {
-        vf_Result result = vf_force_check_constraint( klass, constraint );
-        if( result != VF_OK ) {
-            *error = &(err_message[0]);
-            sprintf(*error, "constraint check failed, class: %s, source: %s, target: %s", class_get_name( klass ), constraint->source, constraint->target);
-            return result;
-        }
-    }
-
-    return VF_OK;
-} // vf_verify_method_constraints
-
-
-/**
-* Function releases verify data in class loader (used to store constraints)
-*/
-void
-vf_release_verify_data( void *data )
-{
-    vf_ClassLoaderData_t *cl_data = (vf_ClassLoaderData_t*)data;
-
-    delete cl_data->string;
-    delete cl_data->hash;
-    delete cl_data->pool;
-} // vf_release_verify_data
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You 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.
+ */
+/** 
+ * @author Mikhail Loenko, Vladimir Molotkov
+ */  
+
+
+
+#include <iostream>
+
+using namespace std;
+
+#include "verifier.h"
+#include "../java5/context_5.h"
+#include "../java6/context_6.h"
+#include "time.h"
+
+using namespace CPVerifier;
+using namespace CPVerifier_5;
+using namespace CPVerifier_6;
+
+static char err_message[5000];
+
+
+/**
+* Function provides initial java-5 verification of class.
+*
+* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
+* and either A or B is not loaded at the moment then a constraint 
+* "class A must be assignable to class B" is recorded into the classloader's data
+*/
+vf_Result
+vf_verify5_class( class_handler klass, unsigned verifyAll, char **error )
+{
+    int index;
+    vf_Result result = VF_OK;
+
+    // Create context
+    SharedClasswideData classwide(klass);
+    vf_Context_5 context(classwide);
+
+    // Verify method
+    for( index = 0; index < class_get_method_number( klass ); index++ ) {
+        result = context.verify_method(class_get_method( klass, index ));
+
+        if (result != VF_OK) {
+            *error = &(err_message[0]);
+            method_handler method = class_get_method( klass, index );
+            sprintf(*error, "%s/%s%s, pass: %d, instr: %d, reason: %s", class_get_name( klass ), method_get_name( method ), 
+                method_get_descriptor( method ), context.pass, context.processed_instruction, context.error_message );
+            break;
+        }
+    }
+
+    /**
+    * Set method constraints
+    */
+    context.set_class_constraints();
+
+    return result;
+} // vf_verify5_class
+
+
+/**
+* Function provides initial java-6 verification of class.
+*
+* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
+* and either A or B is not loaded at the moment then a constraint 
+* "class A must be assignable to class B" is recorded into the classloader's data
+*/
+vf_Result
+vf_verify6_class( class_handler klass, unsigned verifyAll, char **error )
+{
+    int index;
+    vf_Result result = VF_OK;
+
+    // Create contexts
+    SharedClasswideData classwide(klass);
+    vf_Context_5 context5(classwide);
+    vf_Context_6 context6(classwide);
+
+    bool skip_java6_verification_attempt = false;
+
+    // Verify method
+    for( index = 0; index < class_get_method_number( klass ); index++ ) {
+        method_handler method = class_get_method( klass, index );
+
+        //try Java6 verifying (using StackMapTable attribute)
+        if( !skip_java6_verification_attempt || method_get_stackmaptable(method) ) {
+            result = context6.verify_method(method);
+
+            if (result != VF_OK) {
+                //skip Java6 attempts for further methods unless they have StackMapTable
+                skip_java6_verification_attempt = true;
+                if (result == VF_ErrorStackmap) {
+                    //corrupted StackMapTable ==> throw an Error?
+                    *error = &(err_message[0]);
+                    sprintf(*error, "%s/%s%s, reason: %s", class_get_name( klass ), method_get_name( method ), 
+                        method_get_descriptor( method ), context6.error_message );
+                    return result;
+                }
+            }
+        }
+
+        if( result != VF_OK ) {
+            //try Java5 verifying
+            result = context5.verify_method(method);
+            if (result != VF_OK) {
+                //can't verify
+                *error = &(err_message[0]);
+                sprintf(*error, "%s/%s%s, pass: %d, instr: %d, reason: %s", class_get_name( klass ), method_get_name( method ), 
+                    method_get_descriptor( method ), context5.pass, context5.processed_instruction, context5.error_message );
+                return result;
+            }
+        }
+    }
+
+    /**
+    * Set method constraints
+    */
+    context5.set_class_constraints();
+
+    return result;
+} // vf_verify6_class
+
+
+/**
+* Function provides initial verification of class.
+*
+* If when verifying the class a check of type "class A must be assignable to class B" needs to be done 
+* and either A or B is not loaded at the moment then a constraint 
+* "class A must be assignable to class B" is recorded into the classloader's data
+*/
+vf_Result
+vf_verify_class( class_handler klass, unsigned verifyAll, char **error ) {
+    return class_get_version(klass) >= 50 ? vf_verify6_class(klass, verifyAll, error) : vf_verify5_class(klass, verifyAll, error);
+}
+
+/**
+* Function verifies all the constraints "class A must be assignable to class B"
+* that are recorded into the classloader for the given class
+* If some class is not loaded yet -- load it now
+*/
+vf_Result
+vf_verify_class_constraints( class_handler klass, unsigned verifyAll, char **error )
+{
+
+    // get class loader of current class
+    classloader_handler class_loader = class_get_class_loader( klass );
+
+    // get class loader verify data
+    vf_ClassLoaderData_t *cl_data =
+        (vf_ClassLoaderData_t*)cl_get_verify_data_ptr( class_loader );
+
+    // check class loader data
+    if( cl_data == NULL ) {
+        // no constraint data
+        return VF_OK;
+    }
+
+    // get class hash and memory pool
+    vf_Hash *hash = cl_data->hash;
+
+    // get constraints for class
+    vf_HashEntry_t *hash_entry = hash->Lookup( class_get_name( klass ) );
+    if( !hash_entry || !hash_entry->data_ptr ) {
+        // no constraint data
+        return VF_OK;
+    }
+
+    // check method constraints
+    vf_TypeConstraint *constraint = (vf_TypeConstraint*)hash_entry->data_ptr;
+    for( ; constraint; constraint = constraint->next )
+    {
+        vf_Result result = vf_force_check_constraint( klass, constraint );
+        if( result != VF_OK ) {
+            *error = &(err_message[0]);
+            sprintf(*error, "constraint check failed, class: %s, source: %s, target: %s", class_get_name( klass ), constraint->source, constraint->target);
+            return result;
+        }
+    }
+
+    return VF_OK;
+} // vf_verify_method_constraints
+
+
+/**
+* Function releases verify data in class loader (used to store constraints)
+*/
+void
+vf_release_verify_data( void *data )
+{
+    vf_ClassLoaderData_t *cl_data = (vf_ClassLoaderData_t*)data;
+
+    delete cl_data->string;
+    delete cl_data->hash;
+    delete cl_data->pool;
+} // vf_release_verify_data

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/base/ver.cpp
            ('svn:executable' removed)



Mime
View raw message