Fix LDC, LDC_W, and INSTANCEOF opcodes, more debugging
[jamvm-avr32-jem.git] / src / access.c
blob99534e1485ce7db48e6216694b8d4c438ec824cd
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "jam.h"
24 static int isSameRuntimePackage(Class *class1, Class *class2) {
25 if(class1 != class2) {
26 ClassBlock *cb1 = CLASS_CB(class1);
27 ClassBlock *cb2 = CLASS_CB(class2);
29 /* The class loader must match */
30 if(cb1->class_loader != cb2->class_loader)
31 return FALSE;
32 else {
33 /* And the package name */
35 /* If either class is an array compare the element
36 name to get rid of leading array characters (the
37 class loaders are the same) */
39 if(IS_ARRAY(cb1))
40 cb1 = CLASS_CB(cb1->element_class);
42 if(IS_ARRAY(cb2))
43 cb2 = CLASS_CB(cb2->element_class);
45 if(cb1 != cb2) {
46 char *ptr1 = cb1->name;
47 char *ptr2 = cb2->name;
49 /* Names must match at least up to the last slash
50 in each. Note, we do not need to check for NULLs
51 because names _must_ be different (same loader,
52 but different class). */
54 while(*ptr1++ == *ptr2++);
56 for(ptr1--; *ptr1 && *ptr1 != '/'; ptr1++);
58 /* Didn't match to last slash in ptr1 */
59 if(*ptr1)
60 return FALSE;
62 for(ptr2--; *ptr2 && *ptr2 != '/'; ptr2++);
64 /* Didn't match to last slash in ptr2 */
65 if(*ptr2)
66 return FALSE;
70 return TRUE;
73 int checkClassAccess(Class *class1, Class *class2) {
74 ClassBlock *cb1 = CLASS_CB(class1);
76 /* We can access it if it is public */
77 if(cb1->access_flags & ACC_PUBLIC)
78 return TRUE;
80 /* Or if they're members of the same runtime package */
81 return isSameRuntimePackage(class1, class2);
84 static int checkMethodOrFieldAccess(int access_flags, Class *decl_class, Class *class) {
86 /* Public methods and fields are always accessible */
87 if(access_flags & ACC_PUBLIC)
88 return TRUE;
90 /* If the method or field is private, it must be declared in
91 the accessing class */
92 if(access_flags & ACC_PRIVATE)
93 return decl_class == class;
95 /* The method or field must be protected or package-private */
97 /* If it is protected it is accessible if it is declared in the
98 accessing class or in a super-class */
99 if((access_flags & ACC_PROTECTED) && isSubClassOf(decl_class, class))
100 return TRUE;
102 /* Lastly protected and package-private methods/fields are accessible
103 if they are in the same runtime package as the accessing class */
104 return isSameRuntimePackage(decl_class, class);
107 int checkMethodAccess(MethodBlock *mb, Class *class) {
108 return checkMethodOrFieldAccess(mb->access_flags, mb->class, class);
111 int checkFieldAccess(FieldBlock *fb, Class *class) {
112 return checkMethodOrFieldAccess(fb->access_flags, fb->class, class);