Skip to content

Commit

Permalink
[GR-31710] Support building js-launcher with image-builder on module-…
Browse files Browse the repository at this point in the history
…path.

PullRequest: graal/9671
  • Loading branch information
olpaw committed Nov 10, 2021
2 parents 6cae92d + 089232f commit 9358dea
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 74 deletions.
4 changes: 2 additions & 2 deletions sdk/mx.sdk/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@
}
},
"JLINE3" : {
"sha1" : "4cb5f6c20b10912ef3c12f4c4c3ebcdbcbe3a555",
"version" : "3.16.0.1",
"sha1" : "bac1579375a67379d8f308016138f9c37a646dd5",
"version" : "3.16.0.2",
"urls" : ["https://lafo.ssw.uni-linz.ac.at/pub/graal-external-deps/jline3-shadowed-{version}.jar"],
"license" : "BSD-new",
"requires" : ["java.logging"],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,31 @@
Args = --features=com.oracle.svm.thirdparty.jline.JLine3Feature \
-H:JNIConfigurationResources=${.}/launcher.jniconfig
-H:JNIConfigurationResources=${.}/launcher.jniconfig \
--add-modules=java.scripting \
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.base \
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.pointsto \
--add-reads=org.graalvm.launcher=org.graalvm.nativeimage.builder \
--add-exports=org.graalvm.truffle/com.oracle.truffle.object=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.object=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.tree.analysis=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.memory=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.object.dsl=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.exception=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.interop=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.profiles=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.signature=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.dsl=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.tree=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.utilities=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.source=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.library=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.staticobject=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.debug=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.nodes=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.frame=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.instrumentation=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.impl.asm.commons=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.io=ALL-UNNAMED \
--add-exports=org.graalvm.truffle/com.oracle.truffle.api.debug.impl=ALL-UNNAMED
4 changes: 4 additions & 0 deletions substratevm/mx.substratevm/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,7 @@
"com.oracle.svm.core.snippets", # Uses of com.oracle.svm.core.snippets.KnownIntrinsics
"com.oracle.svm.core", # Uses of com.oracle.svm.core.TypeResult
"com.oracle.svm.core.util", # Uses of com.oracle.svm.core.util.VMError
"com.oracle.svm.core.jni", # Uses of com.oracle.svm.core.jni.JNIRuntimeAccess
"com.oracle.svm.jfr", # Uses of com.oracle.svm.jfr.JfrEnabled
"com.oracle.svm.hosted to java.base",
"com.oracle.svm.hosted.agent to java.instrument",
Expand Down Expand Up @@ -1116,6 +1117,7 @@
"com.oracle.truffle.api.TruffleLanguage.Provider",
"com.oracle.truffle.api.instrumentation.TruffleInstrument.Provider",
"com.oracle.svm.hosted.agent.NativeImageBytecodeInstrumentationAgentExtension",
"com.oracle.svm.hosted.NativeImageClassLoaderPostProcessing",
],
"requiresConcealed": {
"jdk.internal.vm.ci": [
Expand All @@ -1137,12 +1139,14 @@
"sun.security.jca",
"sun.security.util",
"sun.security.provider",
"sun.security.ssl",
"com.sun.crypto.provider",
"sun.reflect.generics.repository",
"jdk.internal.org.objectweb.asm",
"sun.util.locale.provider",
"sun.util.resources",
"sun.invoke.util",
"sun.net",
],
"java.management": [
"sun.management",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,6 @@
*/
package com.oracle.svm.core.jdk11;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Objects;

import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
Expand All @@ -39,6 +34,12 @@
import com.oracle.svm.core.jdk.Resources;
import com.oracle.svm.core.jdk.resources.ResourceStorageEntry;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

@SuppressWarnings("unused")
@TargetClass(value = java.lang.Module.class, onlyWith = JDK11OrLater.class)
public final class Target_java_lang_Module_JDK11OrLater {
Expand Down Expand Up @@ -96,6 +97,10 @@ private static void addExportsToAllUnnamed0(Module from, String pn) {

@TargetClass(className = "java.lang.Module", innerClass = "ReflectionData", onlyWith = JDK11OrLater.class) //
private static final class Target_java_lang_Module_ReflectionData {
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
static Target_java_lang_WeakPairMap<Module, Module, Boolean> reads;
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
static Target_java_lang_WeakPairMap<Module, Module, Map<String, Boolean>> exports;
@Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.NewInstance, declClassName = "java.lang.WeakPairMap") //
static Target_java_lang_WeakPairMap<Module, Class<?>, Boolean> uses;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,16 @@

APIOptionKind kind() default APIOptionKind.Default;

char WHITESPACE_SEPARATOR = ' ';

/**
* Provide a custom separator that should be used to separate the option name from its option
* values. The default separator is {@code '='}.
* values. The default separator is {@code '='}. If {@code WHITESPACE_SEPARATOR} is used the
* option value has to be passed as the next argument (i.e., separated by whitespace on the
* command line). It is also allowed to provide more than one separator. See e.g. the options
* defined in {@code com.oracle.svm.hosted.NativeImageClassLoaderOptions}
*/
char valueSeparator() default '=';
char[] valueSeparator() default {'='};

/**
* The value that will be passed to a non-boolean option when no {@code =} is specified.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ public static String commandArgument(OptionKey<?> option, String value, String a
if (apiOption.fixedValue().length == 0) {
if (apiOptionWithValue == null) {
/* First APIOption that accepts value is selected as fallback */
apiOptionWithValue = optionName + apiOption.valueSeparator() + value;
apiOptionWithValue = optionName + apiOption.valueSeparator()[0] + value;
}
} else if (apiOption.fixedValue()[0].equals(value)) {
/* Return requested option expressed as fixed-value APIOption */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class APIOptionHandler extends NativeImage.OptionHandler<NativeImage> {

static final class OptionInfo {
final String[] variants;
final char valueSeparator;
final char[] valueSeparator;
final String builderOption;
final String defaultValue;
final String helpText;
Expand All @@ -76,7 +76,7 @@ static final class OptionInfo {
final List<Function<Object, Object>> valueTransformers;
final APIOptionGroup group;

OptionInfo(String[] variants, char valueSeparator, String builderOption, String defaultValue, String helpText, boolean hasPathArguments, boolean defaultFinal, String deprecationWarning,
OptionInfo(String[] variants, char[] valueSeparator, String builderOption, String defaultValue, String helpText, boolean hasPathArguments, boolean defaultFinal, String deprecationWarning,
List<Function<Object, Object>> valueTransformers, APIOptionGroup group, boolean extra) {
this.variants = variants;
this.valueSeparator = valueSeparator;
Expand Down Expand Up @@ -150,6 +150,7 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
VMError.guarantee(optionDescriptor.getOptionKey() instanceof HostedOptionKey, "Only HostedOptionKeys are allowed to have array type key values.");
optionValueType = optionValueType.getComponentType();
}
boolean hasFixedValue = apiAnnotation.fixedValue().length > 0;
if (optionValueType.equals(Boolean.class)) {
if (!apiAnnotation.group().equals(APIOption.NullGroup.class)) {
try {
Expand Down Expand Up @@ -182,7 +183,7 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
if (apiAnnotation.defaultValue().length > 0) {
VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s) cannot use APIOption.defaultValue", apiOptionName, rawOptionName));
}
if (apiAnnotation.fixedValue().length > 0) {
if (hasFixedValue) {
VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s) cannot use APIOption.fixedValue", apiOptionName, rawOptionName));
}
builderOption += apiAnnotation.kind().equals(APIOptionKind.Negated) ? "-" : "+";
Expand All @@ -201,13 +202,13 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
if (apiAnnotation.fixedValue().length > 1) {
VMError.shouldNotReachHere(String.format("APIOption %s(%s) cannot have more than one APIOption.fixedValue", apiOptionName, rawOptionName));
}
if (apiAnnotation.fixedValue().length > 0 && apiAnnotation.defaultValue().length > 0) {
if (hasFixedValue && apiAnnotation.defaultValue().length > 0) {
VMError.shouldNotReachHere(String.format("APIOption %s(%s) APIOption.defaultValue and APIOption.fixedValue cannot be combined", apiOptionName, rawOptionName));
}
if (apiAnnotation.defaultValue().length > 0) {
defaultValue = apiAnnotation.defaultValue()[0];
}
if (apiAnnotation.fixedValue().length > 0) {
if (hasFixedValue) {
defaultValue = apiAnnotation.fixedValue()[0];
}

Expand Down Expand Up @@ -236,10 +237,26 @@ private static void extractOption(String optionPrefix, OptionDescriptor optionDe
"Class specified as valueTransformer for @APIOption " + apiOptionName + " cannot be loaded or instantiated: " + transformerClass.getTypeName(), ex.getCause());
}
}
if (apiAnnotation.valueSeparator().length == 0) {
throw VMError.shouldNotReachHere(String.format("APIOption %s(%s) does not specify any valueSeparator", apiOptionName, rawOptionName));
}
if (Arrays.asList(apiAnnotation.valueSeparator()).contains(APIOption.WHITESPACE_SEPARATOR)) {
String msgTail = " cannot use APIOption.WHITESPACE_SEPARATOR as value separator";
if (booleanOption) {
throw VMError.shouldNotReachHere(String.format("Boolean APIOption %s(%s)" + msgTail, apiOptionName, rawOptionName));
}
if (hasFixedValue) {
VMError.shouldNotReachHere(String.format("APIOption %s(%s) with fixed value" + msgTail, apiOptionName, rawOptionName));
}
if (defaultValue != null) {
VMError.shouldNotReachHere(String.format("APIOption %s(%s) with default value" + msgTail, apiOptionName, rawOptionName));
}
}
boolean defaultFinal = booleanOption || hasFixedValue;
apiOptions.put(apiOptionName,
new APIOptionHandler.OptionInfo(apiAnnotation.name(), apiAnnotation.valueSeparator(), builderOption, defaultValue, helpText,
apiAnnotation.kind().equals(APIOptionKind.Paths),
booleanOption || apiAnnotation.fixedValue().length > 0, apiAnnotation.deprecated(), valueTransformers, group, apiAnnotation.extra()));
defaultFinal, apiAnnotation.deprecated(), valueTransformers, group, apiAnnotation.extra()));
}
} catch (NoSuchFieldException e) {
/* Does not qualify as APIOption */
Expand All @@ -253,8 +270,7 @@ private static String startLowerCase(String str) {
@Override
boolean consume(ArgumentQueue args) {
String headArg = args.peek();

String translatedOption = translateOption(headArg);
String translatedOption = translateOption(args);
if (translatedOption != null) {
args.poll();
nativeImage.addPlainImageBuilderArg(NativeImage.injectHostedOptionOrigin(translatedOption, args.argumentOrigin));
Expand All @@ -266,16 +282,18 @@ boolean consume(ArgumentQueue args) {
GroupInfo groupInfo = entry.getValue();
String groupName = APIOption.Utils.optionName(groupInfo.group.name());
String supportedValues = "'" + String.join("', '", groupInfo.supportedValues) + "'";
NativeImage.showError("'" + headArg.substring(groupNameAndSeparator.length()) + "' is not a valid value for the option " + groupName + ". Supported values are " + supportedValues);
NativeImage.showError("In " + args.argumentOrigin + " '" + headArg.substring(groupNameAndSeparator.length()) + "' is not a valid value for the option " + groupName +
". Supported values are " + supportedValues);
}
}
}
return false;
}

String translateOption(String arg) {
String translateOption(ArgumentQueue argQueue) {
OptionInfo option = null;
String[] optionNameAndOptionValue = null;
String argumentOrigin = argQueue.argumentOrigin;
found: for (OptionInfo optionInfo : apiOptions.values()) {
for (String variant : optionInfo.variants) {
String optionName;
Expand All @@ -284,29 +302,40 @@ String translateOption(String arg) {
} else {
optionName = APIOption.Utils.groupName(optionInfo.group) + variant;
}
if (arg.equals(optionName)) {
String headArg = argQueue.peek();
if ((optionInfo.defaultFinal || optionInfo.defaultValue != null) && headArg.equals(optionName)) {
option = optionInfo;
optionNameAndOptionValue = new String[]{optionName};
break found;
}
if (arg.startsWith(optionName + optionInfo.valueSeparator)) {
option = optionInfo;
optionNameAndOptionValue = SubstrateUtil.split(arg, Character.toString(optionInfo.valueSeparator), 2);
break found;
for (char valueSeparator : optionInfo.valueSeparator) {
if (valueSeparator == APIOption.WHITESPACE_SEPARATOR && headArg.equals(optionName)) {
argQueue.poll();
String optionValue = argQueue.peek();
if (optionValue == null) {
NativeImage.showError(headArg + " from " + argumentOrigin + " requires option argument");
}
option = optionInfo;
optionNameAndOptionValue = new String[]{headArg, optionValue};
break found;
} else if (headArg.startsWith(optionName + valueSeparator)) {
option = optionInfo;
optionNameAndOptionValue = SubstrateUtil.split(headArg, Character.toString(valueSeparator), 2);
break found;
}
}
}

}
if (option != null) {
if (!option.deprecationWarning.isEmpty()) {
NativeImage.showWarning("Using a deprecated option " + optionNameAndOptionValue[0] + ". " + option.deprecationWarning);
NativeImage.showWarning("Using a deprecated option " + optionNameAndOptionValue[0] + " from " + argumentOrigin + ". " + option.deprecationWarning);
}
String builderOption = option.builderOption;
/* If option is in group, defaultValue has different use */
String optionValue = option.group != null ? null : option.defaultValue;
if (optionNameAndOptionValue.length == 2) {
if (option.defaultFinal) {
NativeImage.showError("Passing values to option " + optionNameAndOptionValue[0] + " is not supported.");
NativeImage.showError("Passing values to option " + optionNameAndOptionValue[0] + " from " + argumentOrigin + " is not supported.");
}
optionValue = optionNameAndOptionValue[1];
}
Expand Down
Loading

0 comments on commit 9358dea

Please sign in to comment.