comparison src/main/gov/nasa/jpf/jvm/JVMSystemClassLoaderInfo.java @ 0:61d41facf527

initial v8 import (history reset)
author Peter Mehlitz <Peter.C.Mehlitz@nasa.gov>
date Fri, 23 Jan 2015 10:14:01 -0800
parents
children 6774e2e08d37
comparison
equal deleted inserted replaced
-1:000000000000 0:61d41facf527
1 /*
2 * Copyright (C) 2014, United States Government, as represented by the
3 * Administrator of the National Aeronautics and Space Administration.
4 * All rights reserved.
5 *
6 * The Java Pathfinder core (jpf-core) platform is licensed under the
7 * Apache License, Version 2.0 (the "License"); you may not use this file except
8 * in compliance with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0.
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18 package gov.nasa.jpf.jvm;
19
20 import gov.nasa.jpf.Config;
21 import gov.nasa.jpf.JPF;
22 import gov.nasa.jpf.util.JPFLogger;
23 import gov.nasa.jpf.vm.ClassFileContainer;
24 import gov.nasa.jpf.vm.ClassInfo;
25 import gov.nasa.jpf.vm.ClassLoaderInfo;
26 import gov.nasa.jpf.vm.ClassParseException;
27 import gov.nasa.jpf.vm.MethodInfo;
28 import gov.nasa.jpf.vm.SystemClassLoaderInfo;
29 import gov.nasa.jpf.vm.VM;
30 import java.io.File;
31 import java.io.IOException;
32
33 /**
34 * a SystemClassLoaderInfo that reads standard Java classfiles from *.class and *.jar files, and creates code using a concrete
35 * value JVM instruction set
36 */
37 public class JVMSystemClassLoaderInfo extends SystemClassLoaderInfo {
38
39 static JPFLogger log = JPF.getLogger("class");
40 protected JVMCodeBuilder defaultCodeBuilder;
41
42 public JVMSystemClassLoaderInfo (VM vm, int appId) {
43 super(vm, appId);
44
45 defaultCodeBuilder = createDefaultCodeBuilder(config, appId);
46
47 // now we can notify
48 vm.registerClassLoader(this);
49 }
50
51 /**
52 * override this if you need a different default CodeBuilder
53 */
54 protected JVMCodeBuilder createDefaultCodeBuilder (Config config, int appId) {
55 String key = config.getIndexableKey("jvm.insn_factory.class", appId);
56 JVMInstructionFactory insnFactory = config.getEssentialInstance(key, JVMInstructionFactory.class);
57 return new JVMCodeBuilder(insnFactory);
58 }
59
60 @Override
61 protected ClassFileContainer createClassFileContainer (String spec) {
62 int i = spec.indexOf(".jar");
63 if (i > 0) {
64 // its a jar
65 int j = i + 4;
66 int len = spec.length();
67 String jarPath;
68 String pathPrefix = null;
69 File jarFile;
70 if (j == len) {
71 // no path prefix, plain jar
72 jarPath = spec;
73 } else {
74 if (spec.charAt(j) == '/') {
75 pathPrefix = spec.substring(j);
76 jarPath = spec.substring(0, j);
77 } else {
78 return null;
79 }
80 }
81 jarFile = new File(jarPath);
82 if (jarFile.isFile()) {
83 try {
84 return new JarClassFileContainer(jarFile, pathPrefix);
85 } catch (IOException ix) {
86 return null;
87 }
88 } else {
89 return null;
90 }
91
92 } else {
93 // a dir
94 File dir = new File(spec);
95 if (dir.isDirectory()) {
96 return new DirClassFileContainer(dir);
97 } else {
98 return null;
99 }
100 }
101 }
102
103 protected void addSystemBootClassPath () {
104 String v = System.getProperty("sun.boot.class.path");
105 if (v != null) {
106 for (String pn : v.split(File.pathSeparator)) {
107 if (pn != null && !pn.isEmpty()) {
108 ClassFileContainer cfc = createClassFileContainer(pn);
109 if (cfc != null) {
110 cp.addClassFileContainer(cfc);
111 }
112 }
113 }
114 } else {
115 // Hmm, maybe we are not executing on OpenJDK
116 }
117 }
118
119 /**
120 * this is the main method to create the ClassPath, which is called from the ctor
121 */
122 @Override
123 protected void initializeSystemClassPath (VM vm, int appId) {
124 Config conf = vm.getConfig();
125 File[] pathElements;
126
127 // explicit "classpath[.id]" settings have precedence
128 pathElements = getPathElements(conf, "classpath", appId);
129 if (pathElements != null) {
130 for (File f : pathElements) {
131 addClassPathElement(f.getAbsolutePath());
132 }
133 }
134
135 // we optionally append boot_classpath
136 pathElements = getPathElements(conf, "vm.boot_classpath", appId);
137 if (pathElements != null) {
138 for (File f : pathElements) {
139 if (f.getName().equals("<system>")) {
140 addSystemBootClassPath();
141 } else {
142 addClassPathElement( f.getAbsolutePath());
143 }
144 }
145 }
146
147 log.info("collected system classpath: ", cp);
148 }
149
150 /**
151 * override this if you have different CodeBuilders for different types
152 * NOTE - this CodeBuilder is not completely initialized yet, clients still have to call startMethod(mi) on it
153 */
154 protected JVMCodeBuilder getCodeBuilder (String clsName) {
155 return defaultCodeBuilder;
156 }
157
158 /**
159 * used for automatically created code such as AnnotationProxies, direct calls, native calls and run starts
160 * NOTE - this cannot be called recursively or concurrently
161 */
162 protected JVMCodeBuilder getSystemCodeBuilder (ClassFile cf, MethodInfo mi) {
163 defaultCodeBuilder.reset(cf, mi);
164 return defaultCodeBuilder;
165 }
166
167 @Override
168 protected ClassInfo createClassInfo (String clsName, String url, byte[] data, ClassLoaderInfo definingLoader) throws ClassParseException {
169 ClassFile cf = new ClassFile(data);
170 JVMCodeBuilder cb = getCodeBuilder(clsName);
171 ClassInfo ci = new JVMClassInfo(clsName, definingLoader, cf, url, cb);
172 setAttributes(ci);
173
174 return ci;
175 }
176 }