/** * Gets the class file corresponding to a given instance class. The <code>klass</code> must not * yet be converted and it must not be a {@link Klass#isSynthetic() synthetic} class. * * @param klass the instance class for which a class file is requested * @return the class file for <code>klass</code> */ ClassFile getClassFile(Klass klass) { Assert.that(!klass.isSynthetic(), "synthethic class has no classfile"); String name = klass.getName(); ClassFile classFile = (ClassFile) classFiles.get(name); if (classFile == null) { classFile = new ClassFile(klass); classFiles.put(name, classFile); } return classFile; }
/** {@inheritDoc} */ public void load(Klass klass) { Assert.that(VM.isHosted() || VM.getCurrentIsolate().getLeafSuite() == suite); int state = klass.getState(); if (state < Klass.STATE_LOADED) { if (klass.isArray()) { load(klass.getComponentType()); } else { lastClassNameStack.push(klass.getName()); ClassFile classFile = getClassFile(klass); load(classFile); lastClassNameStack.pop(); } } }
/** * Generate squawk code for methods of <code>klass</code> when doing whole-suite translation * (inlining, etc.) * * @param klass the klass to generate code for */ void convertPhase2(Klass klass) { Assert.that(translationStrategy != BY_METHOD); convert(klass); if (klass.getState() < Klass.STATE_CONVERTED) { if (!VM .isVerbose()) { // "squawk -verbose" will show the class names as it finishes loading // them, which is progress enough traceProgress(); } lastClassNameStack.push(klass.getName()); ClassFile classFile = getClassFile(klass); classFile.convertPhase2(this, false); classFiles.remove(klass.getName()); lastClassNameStack.pop(); } }
/** {@inheritDoc} */ public void convert(Klass klass) { lastClassNameStack.push(klass.getName()); int state = klass.getState(); if (state < Klass.STATE_CONVERTING) { if (klass.isArray()) { convert(Klass.OBJECT); klass.changeState(Klass.STATE_CONVERTED); } else { traceProgress(); ClassFile classFile = getClassFile(klass); classFile.convertPhase1(this, translationStrategy != BY_METHOD); if (klass.hasGlobalStatics()) { // record globals now. recordGlobalStatics(klass); } if (translationStrategy == BY_METHOD || translationStrategy == BY_CLASS) { // if NOT inlining, then generate squawk code now. classFile.convertPhase2(this, translationStrategy == BY_METHOD); classFiles.remove(klass.getName()); } } } lastClassNameStack.pop(); }
/** Load and converts the closure of classes in the current suite. */ public void computeClosure() { boolean changed = true; while (changed) { changed = false; for (int cno = 0; cno < suite.getClassCount(); cno++) { Klass klass = suite.getKlass(cno); if (klass == null) { continue; // if not floats, or if deferred errors, there can be some missing classes } if (klass.getState() < Klass.STATE_LOADED) { load(klass); changed = true; } if (klass.getState() < Klass.STATE_CONVERTING) { convert(klass); changed = true; } } } }
/** * Like <code>klass</code> must not yet be converted and it must not be a {@link * Klass#isSynthetic() synthetic} class. * * @param klass the instance class for which a class file is requested * @return the class file for <code>klass</code>, or null if that ClassFile has not been * translated by this translator. */ ClassFile lookupClassFile(Klass klass) { Assert.that(!klass.isSynthetic(), "synthethic class has no classfile"); ClassFile classFile = (ClassFile) classFiles.get(klass.getInternalName()); return classFile; }