/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * StandaloneJarGeneratedCodeInfo.java * Created: Jun 8, 2007 * By: Joseph Wong */ package org.openquark.cal.internal.runtime.lecc; import java.io.PrintWriter; import java.io.StringWriter; import org.openquark.cal.runtime.MachineConfiguration; /** * This class represents a generated code info to be used only by the main class generated by the StandaloneJarBuilder. * <p> * The classes in the standalone jar are generated with the machine configuration at "build time". * We capture this configuration into a StandaloneJarGeneratedCodeInfo, to be checked at runtime * against the machine configuration then. * * @author Joseph Wong */ public final class StandaloneJarGeneratedCodeInfo { /** Code generation scheme version. */ private final int codeVersion; /** Does the generated code include runtime statistics. */ private final boolean runtimeStats; /** Does the generated code include call counting. */ private final boolean callCounts; /** Does the generated code include debug support. */ private final boolean debugCapable; /** * Does the generated code directly call primitive operators and foreign functions whenever possible * or does it indirect through fUnboxed calls. */ private final boolean directPrimopCalls; /** Does the generated code ignore strictness annotations. */ private final boolean ignoringStrictnessAnnotations; /** Does this runtime check for external halt commands. */ private final boolean nonInterruptableRuntime; /** * Constructs an instance of this class. This should only be called by a main class generated by the StandaloneJarBuilder. * @param codeVersion Code generation scheme version. * @param runtimeStats Does the generated code include runtime statistics. * @param callCounts Does the generated code include call counting. * @param debugCapable Does the generated code include debug support. * @param directPrimopCalls Does the generated code directly call primitive operators and foreign functions whenever possible * or does it indirect through fUnboxed calls. * @param ignoringStrictnessAnnotations Does the generated code ignore strictness annotations. * @param nonInterruptableRuntime Does this runtime check for external halt commands. */ public StandaloneJarGeneratedCodeInfo( final int codeVersion, final boolean runtimeStats, final boolean callCounts, final boolean debugCapable, final boolean directPrimopCalls, final boolean ignoringStrictnessAnnotations, final boolean nonInterruptableRuntime) { this.codeVersion = codeVersion; this.runtimeStats = runtimeStats; this.callCounts = callCounts; this.debugCapable = debugCapable; this.directPrimopCalls = directPrimopCalls; this.ignoringStrictnessAnnotations = ignoringStrictnessAnnotations; this.nonInterruptableRuntime = nonInterruptableRuntime; } /** * Constructs an instance of this class from the current configuration. * @return an instance of this class. */ public static StandaloneJarGeneratedCodeInfo makeFromCurrentConfiguration() { return new StandaloneJarGeneratedCodeInfo( LECCMachineConfiguration.CODEGEN_VERSION, LECCMachineConfiguration.generateStatistics(), LECCMachineConfiguration.generateCallCounts(), LECCMachineConfiguration.generateDebugCode(), LECCMachineConfiguration.generateDirectPrimOpCalls(), LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS, LECCMachineConfiguration.nonInterruptibleRuntime()); } /** * @return Code generation scheme version. */ public final int getCodeVersion() { return codeVersion; } /** * @return Does the generated code include runtime statistics. */ public final boolean generateRuntimeStats() { return runtimeStats; } /** * @return Does the generated code include call counting. */ public final boolean generateCallCounts() { return callCounts; } /** * @return Does the generated code include debug support. */ public final boolean isDebugCapable() { return debugCapable; } /** * @return Does the generated code directly call primitive operators and foreign functions whenever possible * or does it indirect through fUnboxed calls. */ public final boolean generateDirectPrimopCalls() { return directPrimopCalls; } /** * @return Does the generated code ignore strictness annotations. */ public final boolean isIgnoringStrictnessAnnotations() { return ignoringStrictnessAnnotations; } /** * @return Does this runtime check for external halt commands. */ public final boolean isNonInterruptableRuntime() { return nonInterruptableRuntime; } /** * @return whether the configuration under which the machine code currently associated with the module was generated is * compatible with current options. * * For instance, this will be false if this GeneratedCodeInfo indicates that the module's machine code is not debug capable, * but current options require debug-capable code. */ public boolean isCompatibleWithCurrentConfiguration() { return this.codeVersion == LECCMachineConfiguration.CODEGEN_VERSION && this.runtimeStats == LECCMachineConfiguration.generateStatistics() && this.callCounts == LECCMachineConfiguration.generateCallCounts() && this.nonInterruptableRuntime == LECCMachineConfiguration.nonInterruptibleRuntime() && this.debugCapable == LECCMachineConfiguration.generateDebugCode() && this.directPrimopCalls == LECCMachineConfiguration.generateDirectPrimOpCalls() && this.ignoringStrictnessAnnotations == LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS; } /** * Provides configuration hints if this generated code info is not compatible with the current configuration. * @return a String containing the hints. */ public String getConfigurationHints() { if (codeVersion != LECCMachineConfiguration.CODEGEN_VERSION || ignoringStrictnessAnnotations != LECCMachineConfiguration.IGNORE_STRICTNESS_ANNOTATIONS) { return "This standalone jar is incompatible with this version of the Quark Platform."; } final StringWriter stringWriter = new StringWriter(); final PrintWriter printWriter = new PrintWriter(stringWriter); printWriter.println("The current configuration is incompatible with this standalone jar."); provideHint(printWriter, runtimeStats, LECCMachineConfiguration.generateStatistics(), LECCMachineConfiguration.GEN_STATISTICS_PROP); provideHint(printWriter, callCounts, LECCMachineConfiguration.generateCallCounts(), LECCMachineConfiguration.GEN_CALLCOUNTS_PROP); provideHint(printWriter, nonInterruptableRuntime, LECCMachineConfiguration.nonInterruptibleRuntime(), LECCMachineConfiguration.NON_INTERRUPTIBLE_RUNTIME_PROP); provideHint(printWriter, debugCapable, LECCMachineConfiguration.generateDebugCode(), MachineConfiguration.MACHINE_DEBUG_CAPABLE_PROP); printWriter.flush(); stringWriter.flush(); return stringWriter.toString(); } /** * Provides a configuration hint for a specific property. * @param printWriter the print writer to output the hint to. * @param localValue the local value stored in this instance. * @param currentConfigValue the value according to current configuration. * @param propertyName the name of the associated property. */ private void provideHint(final PrintWriter printWriter, final boolean localValue, final boolean currentConfigValue, final String propertyName) { if (localValue != currentConfigValue) { if (localValue) { printWriter.println("Specify the system property: " + propertyName); } else { printWriter.println("Do not specify the system property: " + propertyName); } } } }