You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ml...@apache.org on 2007/07/16 08:44:56 UTC

svn commit: r556523 [4/4] - in /harmony/enhanced/drlvm/trunk: build/make/components/vm/ vm/vmcore/src/verifier-3363/

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h?view=auto&rev=556523
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h Sun Jul 15 23:44:55 2007
@@ -0,0 +1,282 @@
+/*
+ *  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.
+    */
+    typedef struct vf_TypeConstraint_s vf_TypeConstraint_t;
+    typedef struct vf_Hash vf_Hash_t;
+
+    /**
+    * Verification type constraint structure.
+    */
+    struct vf_TypeConstraint_s {
+        const char *source;         // constraint source class name
+        const char *target;         // constraint target class name
+        vf_TypeConstraint_t *next;  // next constraint
+    };
+
+    //verifier's data stored in classloader
+    typedef struct {
+        Memory    *pool;        // constraint memory pool
+        vf_Hash_t *hash;        // constraint hash table
+        vf_Hash_t *string;      // string pool hash table
+    } vf_ClassLoaderData_t;
+
+
+    class vf_Context_t;
+    struct vf_ValidType {
+        class_handler cls;      //class handler
+        const char*   name;     //name of the class
+    };
+
+#define CLASS_NOT_LOADED ((class_handler)-1)
+
+
+    /**
+    * 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(vf_Context_t *_context, unsigned init_table_size);
+
+        ~vf_TypePool() {
+            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);
+
+
+        class_handler vf_TypePool::sm_get_handler(SmConstant type) {
+            unsigned index = type.getReferenceIdx();
+            assert(index <= currentTypeId);
+            return (validTypes+index)->cls;
+        }
+
+        const char* vf_TypePool::sm_get_refname(SmConstant type) {
+            unsigned index = type.getReferenceIdx();
+            assert(index <= currentTypeId);
+            return (validTypes+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_TOP ) {
+                //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 vf_TypePool::sm_get_const_throwable() {
+            return sm_get_const_existing("java/lang/Throwable", &const_throwable);
+        }
+
+        //return SmConstant (known verification type) corresponding to byte[]
+        //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 vf_TypePool::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(byte 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;
+        }
+
+    private:
+        //ref to the main class of the verifier
+        vf_Context_t *context;
+
+        //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 tableSize;
+        unsigned currentTypeId;
+
+        /*****************/
+        //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 vf_TypePool::check_table() {
+            if( currentTypeId == tableSize - 1) {
+                validTypes = (vf_ValidType*)tc_realloc(validTypes, tableSize+=tableIncr);
+            }
+            return currentTypeId++;
+        }
+
+        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_valid(class_handler from, class_handler to);
+
+} // namespace CPVerifier
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/tpool.h
------------------------------------------------------------------------------
    svn:executable = *

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h?view=auto&rev=556523
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h Sun Jul 15 23:44:55 2007
@@ -0,0 +1,422 @@
+/*
+ *  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 __VER_UTILS_H_
+#define __VER_UTILS_H_
+
+#include <assert.h>
+#include "clog.h"
+#include <iostream>
+using namespace std;
+
+namespace CPVerifier {
+
+    // convenience types
+    typedef unsigned char byte;
+    typedef unsigned short Address;
+
+    //TODO:
+#define tc_free(ptr)                free(ptr)
+#define tc_realloc(ptr, sz)         realloc(ptr, sz)
+#define tc_malloc(sz)               malloc(sz)
+#define tc_calloc(sz1, sz2)         calloc(sz1, sz2)
+#define tc_memcpy(ptr1, ptr2, sz)   vf_memcpy(ptr1, ptr2, sz)
+#define tc_memset(ptr, i1, i2)      vf_memset(ptr, i1, i2)
+
+    //TODO: delegate to compiler
+    inline void *vf_memcpy(void *dest, const void *src, size_t count) {
+        char *d = (char *)dest;
+        const char *s = (const char *)src;
+        for (; count; count--) {
+            *d++ = *s++;
+        }
+        return dest;
+    }
+
+    //TODO: delegate to compiler
+    inline void *vf_memset(void *dest, int val, size_t count) {
+        char *d = (char *)dest;
+        char v = (char) val;
+        for (; count; count--) {
+            *d++ = v;
+        }
+        return dest;
+    }
+
+    /**
+    * Structure of hash entry.
+    */
+    struct vf_HashEntry_t {
+        const char *key;            // hash entry key
+        int key_size;               // hash entry key size
+        void *data;                 // pointer to hash entry data
+        vf_HashEntry_t *next;       // next hash entry
+    };
+
+
+
+    class Stack {
+    protected:
+        int max_depth;
+        Address* stack;
+        int depth;
+
+    public:
+        Stack() :
+          max_depth(0), stack(0), depth(0)
+          {}
+
+
+          ~Stack() {
+              tc_free(stack);
+          }
+
+          void push(Address value) {
+              if( depth == max_depth ) {
+                  max_depth += max_depth/2 + 32;
+                  stack = (Address*) tc_realloc(stack, sizeof(Address) * max_depth);
+              }
+
+              stack[depth++] = value;
+          }
+
+          Address pop() {
+              assert(depth > 0);
+              return stack[--depth];
+          }
+
+          bool is_empty() {
+              return !depth;
+          }
+
+          void init() {
+              depth = 0;
+          }
+    };
+
+    class FastStack : Stack {
+    public:
+        FastStack() : fdepth(0) 
+        {}
+
+        void push(Address value) {
+            if( fdepth < BUFSIZE ) {
+                buffer[fdepth++] = value;
+            } else {
+                Stack::push(value);
+            }
+        }
+
+        Address pop() {
+            assert(fdepth > 0);
+            return Stack::is_empty() ? buffer[--fdepth] : Stack::pop();
+        }
+
+        bool is_empty() {
+            return !fdepth;
+        }
+
+        void init() {
+            fdepth = 0;
+            Stack::init();
+        }
+
+    private:
+        static const int BUFSIZE = 100;
+        int fdepth;
+        Address buffer[BUFSIZE];
+    };
+
+    class MarkableStack : public FastStack {
+        // contains the following entries:
+        // <address, mark> no mask means zero mark
+
+        // <non-zero address, 0> is pushed as {address}
+        // <0, 0> is pushed as {0, 0}
+        // <any address, non-zero mark> is pushed as {address, mark, 0}
+
+    public:
+        void xPop(Address *addr, short *mark) {
+            *addr = pop();
+            *mark = (*addr) ? 0 : pop();
+
+            if( *mark ) {
+                *addr = pop();
+            }
+        }
+
+        void xPush(Address value) {
+            if( value ) { 
+                push(value);
+            } else {
+                push(0);
+                push(0);
+            }
+        }
+
+        void xPush(Address addr, short m) {
+            push(addr);
+            push(m);
+            push(0);
+        }
+    };
+
+    struct MemoryPageHead {
+        MemoryPageHead *next;
+        size_t size;
+
+        MemoryPageHead *get_next(size_t min_size, size_t max_size) {
+            assert(this);
+            MemoryPageHead *ret = this;
+            while ( ret->next && ret->next->size < min_size ) {
+                ret = ret->next;
+            }
+
+            return ret->next ? ret->next : (ret->next = create_next(max_size));
+        }
+
+        MemoryPageHead *create_next(size_t max_size) {
+            MemoryPageHead *ret =(MemoryPageHead*)tc_malloc(max_size + sizeof(MemoryPageHead));
+            ret->size = max_size;
+            ret->next = 0;
+            return ret;
+        }
+    };
+
+    class Memory {
+        MemoryPageHead *static_page;
+        MemoryPageHead *current_page;
+
+        static const int STATICSZ = 2000;
+        byte           static_mem[STATICSZ + sizeof (MemoryPageHead) ];
+
+        size_t  page_size;
+        size_t  used;
+    public:
+        Memory() 
+        {
+            //in 90% of cases no memory allocation will be required
+            static_page = (MemoryPageHead *)&static_mem;
+            static_page->next = 0;
+            static_page->size = STATICSZ;
+
+            init();
+        }
+
+        ~Memory() {
+            current_page = static_page->next;
+            while (current_page) {
+                MemoryPageHead *next = current_page->next;
+                tc_free(current_page);
+                current_page = next;
+            }
+        }
+
+        void init() {
+            used = 0;
+            current_page = static_page;
+            page_size = current_page->size;
+        }
+
+        void *malloc(size_t sz) {
+            size_t need_on_page = used + sz;
+
+            if( need_on_page > page_size ) {
+                //create next page
+
+                //define new page size - some heuristic formula. subject to change
+                size_t desired_size = need_on_page + need_on_page/2 + 128;
+
+                //allocating next page
+                current_page = current_page->get_next(sz, desired_size);
+                if( !static_page ) {
+                    static_page = current_page;
+                }
+                used = 0;
+                page_size = current_page->size;
+            }
+
+            void *ret = (byte*)current_page + sizeof(MemoryPageHead) + used;
+            used += sz;
+            return ret;
+        }
+
+        void *calloc(size_t sz) {
+            void *ret = malloc(sz);
+            tc_memset(ret, 0, sz);
+            return ret;
+        }
+
+        void dealloc_last(void* ptr, size_t sz) {
+            assert( ((byte*)ptr) + sz == (byte*)current_page + sizeof(MemoryPageHead) + used );
+            used -= sz;
+        }
+    };
+
+    /**
+    * Verifier hash table structure.
+    */
+    struct vf_Hash {
+    public:
+        /**
+        * Hash table constructor.
+        * @note Function allocates memory for hash pool and hash table.
+        */
+        vf_Hash() 
+        {
+            memoryPool.init();
+            m_hash = (vf_HashEntry_t**)memoryPool.calloc(HASH_SIZE * sizeof(vf_HashEntry_t*));
+            assert((0xFFFFFFFF & HASH_MASK) + 1 == HASH_SIZE );
+        } // vf_Hash::vf_Hash
+
+
+        /**
+        * Function looks up hash entry which is identical to given hash key.
+        * @param key - given hash key
+        * @return Hash entry which is identical to given hash key.
+        * @see vf_HashEntry_t
+        */
+        vf_HashEntry_t * Lookup( const char *key ) {
+            assert( key );
+            int length = (int)strlen(key);
+
+            unsigned hash_index = HashFunc( key, length );
+
+            vf_HashEntry_t *hash_entry = m_hash[hash_index];
+            while( hash_entry != NULL ) {
+                if( CheckKey( hash_entry, key, length ) ) {
+                    return hash_entry;
+                }
+                hash_entry = hash_entry->next;
+            }
+            return NULL;
+        } // vf_Hash::Lookup( key )
+
+
+        /**
+        * Function creates hash entry which is identical to given hash key.
+        * @param key - given hash key
+        * @param length - length for the key
+        * @return Hash entry which are identical to given hash key.
+        * @see vf_HashEntry_t
+        * @note Created hash key and hash entry is allocated into hash memory pool.
+        */
+        vf_HashEntry_t * NewHashEntry( const char *key, int length ) {
+            // lookup type in hash
+            assert( key );
+            unsigned hash_index = HashFunc( key, length );
+
+            vf_HashEntry_t *hash_entry = m_hash[hash_index];
+            while( hash_entry != NULL ) {
+                if( CheckKey( hash_entry, key, length ) ) {
+                    return hash_entry;
+                }
+                hash_entry = hash_entry->next;
+            }
+
+            if( !hash_entry ) {
+                // create key string
+                char *hash_key = (char*)memoryPool.malloc( (length & (~3)) + 4);
+                tc_memcpy( hash_key, key, length );
+                hash_key[length] = 0;
+
+                hash_entry = (vf_HashEntry_t*)memoryPool.malloc(sizeof(vf_HashEntry_t));
+                hash_entry->key = hash_key;
+                hash_entry->key_size = length;
+                hash_entry->next = m_hash[hash_index];
+                hash_entry->data = 0;
+                m_hash[hash_index] = hash_entry;
+            }
+
+            return hash_entry;
+        } // vf_Hash::NewHashEntry( key, length )
+
+        /**
+        * Function creates hash entry which is identical to given hash key.
+        * @param key - given hash key
+        * @return Hash entry which are identical to given hash key.
+        * @see vf_HashEntry_t
+        * @note Created hash key and hash entry is allocated into hash memory pool.
+        */
+        vf_HashEntry_t * NewHashEntry( const char *key) {
+            return NewHashEntry(key, (int)strlen(key));
+        } // vf_Hash::NewHashEntry( key )
+
+    private:
+        static const unsigned HASH_SIZE = 128;   ///< hash table size
+        static const unsigned HASH_MASK = 127;   ///< hash table mask to avoid division
+
+        Memory memoryPool;
+        vf_HashEntry_t **m_hash;    ///< hash table
+
+        /**
+        * Function checks key identity.
+        * @param hash_entry - checked hash entry
+        * @param key        - checked key
+        * @return If keys are identical function returns <code>true</code>,
+        *         else returns <code>false</code>.
+        * @see vf_HashEntry_t
+        */
+        int CheckKey( vf_HashEntry_t *hash_entry, const char *key, int length) {
+            if( hash_entry->key_size != length ) return false;
+
+            const char* h_key = hash_entry->key; 
+            int idx = 0;
+
+            for( ; idx < length - 3; idx += 4 ) {
+                if( *((int32*) (key+idx) ) != *((int32*) (h_key+idx) ) ) return false;
+            }
+
+            for( ; idx < length; idx++) {
+                if( *(key+idx) != *(h_key+idx) ) return false;
+            }
+
+            return true;
+        }
+
+        /**
+        * Hash function.
+        * @param key - key for hash function
+        * @return Hash index relevant to key.
+        */
+        unsigned vf_Hash::HashFunc( const char *key, int length ) {
+            unsigned result = 0;
+
+            int idx = 0;
+
+            for( ; idx < length - 3; idx += 4 ) {
+                result += *((int32*) (key+idx) );
+            }
+
+            for( ; idx < length; idx++) {
+                result += *(key+idx);
+            }
+
+            byte *bres = (byte*) &result;
+
+            return (bres[0] + bres[1] + bres[2] + bres[3]) & HASH_MASK;
+        } // vf_Hash::HashFunc( key )
+
+    }; // struct vf_Hash
+
+} // namespace CPVerifier
+
+
+#endif

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/ver_utils.h
------------------------------------------------------------------------------
    svn:executable = *

Added: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp?view=auto&rev=556523
==============================================================================
--- harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp (added)
+++ harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp Sun Jul 15 23:44:55 2007
@@ -0,0 +1,93 @@
+/*
+ *  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 "verifier.h"
+#include "context.h"
+#include "time.h"
+
+namespace CPVerifier {
+
+    /**
+    * Function checkes constraint for given class.
+    * Function loads classes if it's needed.
+    */
+    vf_Result
+        vf_force_check_constraint( class_handler klass, 
+        vf_TypeConstraint_t *constraint )    // class constraint
+    {
+        // get target class
+        class_handler target = vf_resolve_class( klass, constraint->target, true );
+        if( !target ) {
+            return VF_ErrorLoadClass;
+        }
+
+        // get stack reference class
+        class_handler source = vf_resolve_class( klass, constraint->source, true );
+        if( !source ) {
+            return VF_ErrorLoadClass;
+        }
+
+        // check restriction
+        if( !vf_is_valid( source, target ) ) {
+            return VF_ErrorIncompatibleArgument;
+        }
+        return VF_OK;
+    } // vf_force_check_constraint
+
+
+    /**
+    * Returns true if 'from' is assignable to 'to' in terms of verifier, namely:
+    * if 'to' is an interface or a (not necessarily direct) super class of 'to'
+    */
+    int vf_is_valid(class_handler from, class_handler to) {
+        if( class_is_interface_(to) ){
+            return true;
+        }
+
+        while (from) {
+            if( from == to ) return true;
+            from = class_get_super_class(from);
+        }
+        return false;
+    }
+
+    /**
+    * Function receives class by given class name, loads it if it's needed.
+    */
+    class_handler
+        vf_resolve_class( class_handler k_class,    // current class
+        const char *name,         // resolved class name
+        bool need_load)      // load flag
+    {
+        // get class loader
+        classloader_handler class_loader = class_get_class_loader( k_class );
+
+        // receive class
+        class_handler result;
+        if( need_load ) {
+            result = cl_load_class( class_loader, name );
+        } else {
+            result = cl_get_class( class_loader, name );
+        }
+
+        return result;
+    } // vf_resolve_class
+
+} // namespace CPVerifier

Propchange: harmony/enhanced/drlvm/trunk/vm/vmcore/src/verifier-3363/vf_resolve.cpp
------------------------------------------------------------------------------
    svn:executable = *