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 = *